Jump to content
MakeWebGames

PHP Functions and Mysqli INSERT INTO problem


Coly010

Recommended Posts

That's what I don't get, why after getting drunk do you even have time or even THINK about coming onto a computer, I get drunk and pass out, is that just me or....?????

Nope, not just you, that's pretty much my game plan when i drink too.

I dont even use my phone when im drunk, other wise i will do something i regret

Link to comment
Share on other sites

  • 2 months later...

Maybe try-it like this... It's with 2 exceptions. One is fatal, the other one will give you a MySQL error number and a message.

 

class eFatalException extends Exception { public function __construct($message) { parent::__construct($message); } }
class eDBException extends Exception { public function __construct($message, $code=-1) { parent::__construct($message, $code); } }

class clsDB {
 protected $prvLink;
 public function __construct($host, $username, $password, $schema=null) {
   if($this->prvLink = mysqli_connect($host, $username, $password)) {
     if(isset($schema)) { $this->selectSchema($schema); } }
   else { throw new eFatalException("Could not logon."); } }
 public function query($sql) {
   if($result = mysqli_query($this->prvLink, $sql)) { return $result; }
   else { throw new eDBException(mysqli_error($this->prvLink), mysqli_errno($this->prvLink)); }
 }
 public function selectSchema($schema) { return mysqli_select_db($this->prvLink, $schema); }
 public function link() { return $this->prvLink; }
}

 

But, how do i know it will give me a exception ?

Because of the other part of coding..... called: testing ! (It comes after designing, but before documenting)


// ----- Test params -----
$host = "127.0.0.1";
$username = "xxxxxx";
$password = "xxxxxx";
$schema = "xxxxxx";
// -----------------------

//  1 - First test: what is going to happen when we try a big pile of BS.... Expected: eFatalExeption !
try {$DB = new clsDB("ThisIsNotMyServer^%&*(()!!!!","MyNameIsNothing", null, "Yes, please!"); }
catch (eFatalException $e) {
 $Test1Passed=true;
} catch (exception $e) {
 $Test1Passed=false; // <-- Just testing... \o/  (You never know, have seen stranger things....)
} if(!$Test1Passed) { echo "FAILED - DB Connection Test 1 - eFatalException expected but not catched.\n"; }

//  2 - Next: Let's try to logon with no schema..... Expected: getting a valid connection.
try {$DB = new clsDB($host, $username, $password); }
catch (exception $e) { echo "FAILED - DB Connection Test 2 - exception not expected.\n"; }
if(!isset($DB)) { echo "FAILED - DB Connection Test 2 - Valid connection Link not returned.\n"; }

//  3 - Let's try to select a schema. (Warning: Dependend on previous test)
if($DB->selectSchema("not_existing_schema")==true) { echo "FAILED - DB Connection Test 3 - not existing schema selected.\n";  }
if($DB->selectSchema($schema)==false) { echo "FAILED - DB Connection Test 3 - could not select schema\n";  }

//  4 - Let's try to query BS
try {
 $DB->query("Hello db, can you give me some records.... please.... please...... please with a little bit of shugar on top ?"); }
catch (eDBException $e) {
 if($e->getCode()==1064) { $Test4Passed=true; }
} if(!$Test4Passed) { echo "FAILED - DB query Test 4 - eDBException expected with MySQL error 1064 `syntax error`.\n"; }


//  5 - Let's try to query something that actualy works.
try { $result=$DB->query("SHOW TABLES"); }
catch (eDBException $e) { echo "FAILED - DB query Test 5 - no eDBException expected.\n"; }
if(!isset($result)) { echo "FAILED - DB query Test 5 - result expected, check your selected schema if there are actual tables in it !\n"; }

 

 

Happy Coding: Roger.

@ Coli010:

$db->query("SELECT * FROM users WHERE userid = '$s_id'");

Is this the DATA for the user it self ? Maybe store this in session vars, a `relational` database is for storing relations. For storing data we use files a very long time. :D

 

You can remove the switch or IF-Branching with a interface. Like: iNotifiable and that has a method called: Notify($u_id, $***, $sid, $t, $ot, $grrr) or something more explaining..... like: Notify($thisPerson, .....)

*switch ($type)
****{
********case 1:
************friend_request($uid, $s_id, $type, $other);
************break;
********case 2:
************new_pm($uid, $s_id, $type, $other);
************break;
********case 3:
************new_chat($uid, $s_id, $type, $other);
************break;
****}

 

interface iNotifiable 
{  public function sendMessage($fromUserID, array $toUsersIDs, $messageParser);  // <- Or something like this.
// Make API not to specific and use lists if possible. Send One or Multiple messages in one API, reduces duplicate functions that do the same things slightly different.
}

class cPersonalMessage implements iNotifiable {
 public function sendMessage($fromUserID, array $toUsersIDs, $messageParser, clsDB $db) {
   $toUserID = array_shift($toUsersIDs) // <-- Personal message has only one reciever !
   $message =  $messageParser($fromUserID, array($toUserID)); // Parser expects multiple ofcourse ;-)
   $db->query("insert into `notifications` (toUserID, fromUserID, message) Values ($toUserID, $fromUserID, $message)");
 }
}

// Usage:

// Script that read's the input from user. (But is clueless about WITH db or USER or other stuff, SEPERATION OF LOGIC keeps the code clean !)
$a = new ........? <- something that is iNotifible (Like a PM message or other notification message)


// Here we do need a handle to the DB and the userID from the people to send a message. But we don't care about WHAT message it's is. One code for ALL messages, no IF-Else trees.
try {
 $a->sendMessage(...,....
} catch (eDBException $e) { echo "***?"; }

 

The IF statement is moved to a better location.. the creation in the beginning. So code doesn't know or say all the different type of messages. Makes the code messy and hard to maintain.

What's the difference. Adding a new message notification in the future. I only have to implement a interface with the correct API and i'm done.

 

Happy Hacking: Roger.

 

Ps: If you inject all your dependencies like: function WhatDoIDo($INeedAFileName, $INeedADelimiter) // <- Maybe loading a file and explode it with a delimiter perhaps ?

Than you have less to document. Because i know that i'm not going to use `global`.

So this function isn't going to logon in a database without knowing. Or do other strange stuff thanx to `side-effects`.

Like filling in your password and username at the wrong host. :o (The best passwords to store are the ones that didn't work. \o/)

Brainfood:

http://en.wikipedia.org/wiki/Side_effect_(computer_science)

http://en.wikipedia.org/wiki/Dependency_injection

Ps: before i going to sleep. You don't need objects ofcourse.

$messageSender = function($fromUserID, array $toUsersIDs, $messageParser, clsDB $db) {

... enter specific MESSAGE code here....

}

.... some where else ....

$messageSender(...,...,...,...); <- Does not know what type of message it is. So when you remove a type. This isn't the place to look for bugs ! (The implementation is at 1 place, for every message type)

 

According to tests of the owner of this site, it will be 46% faster than the OOP aproach. (But learn that first, it's more used than labda expressions)

 

Happy Hacking: Roger

But before we going to try to make better and cleaner code out of this let's do a grand re-design....

(1) - Your putting HTML code in a database. But HTML is a markup language, example:

<div id="notify_new">

<script data-interval="5000">getPageID("notify_new","notification.php?id=last")</script>

</div>

This will get do a request every 5 seconds and if he get's HTML result he will parse this in the div with id="notify_1".

The result it self could be the HTML you want to show with the data inside it.

But the next thing is also posible:

HTML (Template to fill in, already in HTML but you can't see it.)

<a href="javascript:void(0)" id="notify_link"><h1 id="notify_title"></h1><p id="notify_text_short"></p></a>

<script data-interval="5000">getXML(notification.php?id=last")</script>

 

XML: (Until we fill it in with a XML file)

<singleItem>

<notify>

<link onclick="getPageID("main-content", "showNotification.php&item=1")"></link>

<title>Isn't this game boring ?</title>

<text_short>Yes, it is a boring game, i....</text_short>

</notify>

</singleItem>

Thus: you only need files for this, not a database. (connectiong to db cost a lot of time, filesystem is also a database for storing files in directories.)

Just make a XML file for every user that get's a message.

The script will check every 5 seconds if the user has a message.

If he has he will give back the XML of the newest. (order by filemodification date)

Root\Users\$UserID(from session)\Notifications\ <- Xml goes in here, and let's say: 50 files is max, so we going to delete 51th file and more from old to new.

------------------------------------------------------------------------------------------------------------------------------------

(2) Your getting user info from db that doesn't change. Maybe try to store this in session varables. But WARNING: Not to mutch. Loading session vars also cost performance. (So, don't store the actual picture in it!)

That way we can do a lot of stuff without connection to a database. Maybe the user just needs a private file that he only can see. You only need his id to find the right user folder.

But because this is a `security` thing you want to have proper TESTED functions. So you know nobody can cheat in your game, or take controll.

So the function has to deside if the person is loged on, if not he is always a GUEST. So, no `null` or empty array. Makes your code very messy with: if(isset(pileofBS)) {...jada, jada, jada....

Thus not loged on, no problem. We have a dir for guests that's empty or what ever. or the same files than normal but with content: <body><h1>please logon (you bastard)</h1></body>

That way you don't need IF-Then-Else statements for every thing a user does. One go for all users, loged on or not. Makes code less specific, and you can see the FLOW of the program. Not the special cases.

 

---------------------------------------------------------------------------------------------------------------------------------------

(3) Inserting into database isn't `game` logic. Please seperate !

You have a MySQL database now, but what if they change that. Or the people from PHP going to create: MySQLiExtensionOfMySqliExtendingTheOldMySQLiButExtendedWithTheParamsUpSideDown

What you wanted to is ? NotifyPersons, or not. Than call it also that way.

So you have a: function notifyPersons(...,..,..) and that function is going to call a OTHER function. Example: toFile::notifyPerson(..,...,..) or toDB::notifyPerson(..,...,..) or testFramework::notifyPerson(..,...,..)

So in: PHP GAME file -> there only call's to `notifyPersons` but NO implimentation. Only the API/Interface what you going to send/need to do this, just like MySQL is a interface in PHP. (Gang of Four: 1994)

Then in your: Database Model File, you can insert these values.

In your filesystem file: You can append this to a Log file.

In your testFramework file: You can store all `links` (dependancies) and check them if they work. Check HTML for non html5 compatible markup. You name it. If you have the idea's, you can automate almost everything !

 

What file he is going to be used is desided by the `CONTEXT` your program is running in.

Like:

$WhatTimeIsItInTheGame = function() { return Time(); }

$Context = new context($WhatTimeIsItInTheGame, ) <-- production/running game

$TheFirstDayOfTheMonthBug = function() { return '1-1-2010'; }

$Context = new context($TheFirstDayOfTheMonthBug, ) <-- testing/debugging a bug a user found yesterday

 

$context->notifyPersons(getUserId(), $usersToNotify, $message) '<- What is this going to do ? I DON'T KNOW, AND I DON'T WANT TO ! (If i know: "i'm dependand on it")

 

So, we have `notifying` a person loosly coupled from the game it self.

Thus if you need a notification system in the future. You don't have to develop/write/test/document a complete new one.

This system doesn't know about DB, File or Mafia Game. So it doesn't care about these things. It's decoupled and generic if designed correctly.

 

Happy Hacking: Roger.

 

Brainfood:

http://en.wikipedia.org/wiki/Coupling_(computer_programming)

Wiki quote: "Low coupling is often a sign of a well-structured computer system and a good design, and when combined with high cohesion, supports the general goals of high readability and maintainability.["

 

It is mind-blowing that people cannot debug the most simplest of problems; worse that they write non-defensive code which makes debugging hard.

Consider:

mysql_query('INSERT INTO table VALUES (1, 2, "three")')

vs

$sql = 'INSERT INTO TABLE (field1, field2, field3) VALUES (1, 2, "three")';
if (array_key_exists('debug', $_GET)) {
   echo $sql . "<br>";
}
$rs = mysql_query($sql);
if ($rs === false) {
   echo __FILE__ . ':' . __LINE__ . ' -- ' . mysql_error() . '<br>' . $sql;
}

Not an elegant way of displaying error messages I admit, but it does:

a) Define the SQL statement prior to using it - helpful during debugging, especially if you use something like PHP Storm

b) Define each field - In case you change the table structure at a later date.

c) Displays the SQL statement if debugging - No elegantly, but this is more about defensive programming than style.

d) Checks the result of the query

e) Displays an error message if the query failed - Again, not pretty, but you get the point.

Yes, there is more code to type; but in its defence, if a problem does arise, you will be able to see the exact error message, where it is being output and the actual query that caused the problem. Obviously you would need something more secure than simply passing ?debug to the script, but again that's not the point here.

Write your code so that you can easily debug it; any complex variable that gets generated over several lines of code and/or is populated with data from a variety of insecure sources (ie user input) should have something that enables you to quickly show its value *PRIOR* to using it.

 

Exelent: Make a proper function or class out of this and your hired !

Fixing bugs takes more time than programming. But only the people that have actually completed something know this.

Don't code for speed, code for readablility (what does this do), maintainability (how can i add functionalitity to this) and stability (what goes wrong when this isn't going to work somehow ?).

If your finnished product isn't fast enough. It's easy to find the slowing downpart. It's mosly the most used part not to worst coded part.

So you only can do real optimalizations with performance, if it's ready and you know what is going to be used when, and how often.

 

Happy Hacking: Roger

@Alan: Consider:vsNot an elegant way of displaying error messages I admit,

No problem, make 2 functions out of this. One for production the other for testing/development and other stuff.

Swap the function before shipping, and your done.

 

Happy Hacking: Roger.

 

Ps: The time you spent writing elegant error system, can also be used to keep the error's out of the project. I reather write a test that i can re-run after every change, than creating a fansie a error system.

Becasue when your ready to ship the product, your error system should be empty. (At least try to....)

Edited by Dominion
6 posts in a row?
Link to comment
Share on other sites

@Alan: Consider:vsNot an elegant way of displaying error messages I admit,

No problem, make 2 functions out of this. One for production the other for testing/development and other stuff.

Swap the function before shipping, and your done.

 

Happy Hacking: Roger.

 

Ps: The time you spent writing elegant error system, can also be used to keep the error's out of the project. I reather write a test that i can re-run after every change, than creating a fansie a error system.

Becasue when your ready to ship the product, your error system should be empty. (At least try to....)

Surely you are a bot?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...