PHP Tutorials
- Basic PHP Includes
- by esoomllub
While it seems like a basic PHP programming strategy that all developers should know, I find quite regularly that when I am hired to work on existing sites, PHP includes are either not being used or are being used in the most bizarre manner. This tutorial lays out the most PHP includes steps. - Placing Database Rows Into Arrays
- by esoomllub
Placing database rows into arrays is a simple process in MySql. I'll show you a quick function based approach, that you can drop right into your code.
More PHP Tutorials - Powered by PHPFreaks
- 10 Signs of Crappy PHP Software - by
Like it or not, as a professional developer, sooner or later you are going to do some customising (if you are lucky, "extending") of existing software.
If you are not familiar with the software, it is good advice to look into it before accepting the job. I had to learn that the hard way. But how do you recognize crappy applications without getting knee deep into the code? 10 pointers to identify crappy PHP software quickly...
1. The software tries to reinvent the object model, or "fix" language features.
See if you can find a class called "Object". If you find it, it's a pretty clear indication that the author is in the business of trying to reinvent the object model (most commonly because of his own lacking understanding of OO). It is safe to assume that his "fixes" won't stop there. Unplug your phone and hide under your desk.
2. The code includes user defined global variables
A search in the code for "global" or "$GLOBALS" may reveal something like this:
- global $database, $my, $mainframe;
The infamous global variable. If you can tell me what those last two variables contain you are either intimate with the software I pulled it from, or you're psychic. Unlimited bonus points if you can say what code has had it's claws on it before execution flow got to this point. In short, steer well clear.
3. Scattered HTML and SQL
Search for some common SQL and HTML strings. You should be able to determine very quickly whether these are appropriate places for HTML or SQL. If you find HTML and SQL in the same file, "crappyness" is most definitely confirmed.
4. Classes do too much
Find the 3 largest class files by bit size. Take a look at the class name. Does it indicate a distinct responsibility? Look at the methods. Are the tasks they perform closely related? If not, run away screaming.
5. Lots of properties are public or lots of properties are static
If lots of properties are declared "public static", triple your quote. If I have to explain why, maybe there's an open position on the development team of the software for you.
6. Multiple levels of inheritance
More than 2 levels inheritance should be avoided like the plague. I stake my life on the resulting objects having too much unrelated behaviour (ok, maybe not my life, but if you find a proper use of more than 2 levels of inheritance, I'll buy you a beer).
7. The authors try to use Design Patterns
Whether or not the authors have a clue is easily determined by searching for some of the most common design patters. Search the code base and/or documentation for "factory", "decorator", "strategy" etc. If present, you can pretty quickly determine whether the authors know their stuff or are trying to look interesting. That is, if you know how the code should look. If not, refuse to take the project until you do.
8. The software messes with the error level
Well written applications run fine at any error level. Searching the files for /error_level\(.*\)/ should do the trick. In case of hits, try replacing the value with E_STRICT. That's little more than a formality though.
9. In the code base, there is a directory called "core"
This is usually used as an excuse to have the whole application dependent on whatever is in there. Despite the appeal of the term (it does make the contents sound pretty cool and important), defining a "core" is a sign of bad design.
10. The software uses it's own template language.
Be afraid. Very afraid. These guys are definitely in the business of reinventing the wheel. Ignore this warning and you will find yourself spending the better part of a day simulating a "for" loop.
- Using MySQL Administrator with WampServer - by
For those readers who do not develop PHP on Windows platform WampServer is probably the most popular Apache + MySQL + PHP package for Windows. MySQL Administrator on the other hand, is a part of MySQL GUI Tools package.
The problem with this pair, is that they don't want to work together. At least not right out of box. MySQL Administrator fails to find mysql service process as installed by WampServer. This leads to infamous 'Could not find settings' error message.

You still will be able to use MySQL Administrator, but some of its features will be unavailable - among them quite important 'Startup variables' that lets you configure your server.
The reason is simple. WampServer keeps MySQL's config file in a directory, that is not checked by MySQL Administrator's searching algorithm.
Luckily, the solution is also simple.
Open registry editor
Windows XP: Go to Start > Run... type in regedit and press Enter
Vista: Go to Start, type regedit into search box and press EnterA word of warning: be careful when using registry editor, as you might break your system if you change wrong variables.
Using tree on the left go to:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\wampmysqldIn the window on the right find ImagePath variable, double click it's name.
In the dialog that opens you should see something like this:
c:\wamp\bin\mysql\mysql5.1.33\bin\mysqld.exe wampmysqld
(MySQL's version may vary)Change it like this:
"c:\wamp\bin\mysql\mysql5.1.33\bin\mysqld.exe" --defaults-file="c:\wamp\bin\mysql\mysql5.1.33\my.ini" wampmysqld
(be careful not to miss any double quotes!Close registry editor, then restart you MySQL server from WampServer's tray menu.
MySQL Administrator should work fine now.
That would be it ;)
----
MySQL Forums post, where I've found this solution
- SSH Auto-mount Network Share - by
(Beware - This blog/tutorial is directed towards linux based users)
When doing any type of work, especially web work, one of the royal pains is FTPing to your server, or any type of file transfer. Well now you can make it quick and painless. Let me introduce SSHFS. There are 3 major components when creating the SSHFS, and I will guide you through creating and installing all of the necessary steps. Now you can mount and use your file system to automatically upload files and folders to your server with ease.The 3 Major components:
- SSH Automatic Login
- Install SSHFS
- Mount your folder(s)
SSH Automatic Login
Run this command (with the obvious variable substitutions). It should create a public ssh key on your server.
ssh-copy-id [-i [identity_file]] [user@]machine
- ssh-keygen -t dsa
- ssh-copy-id user@machiner.
Check to make sure it's there, the file should be called, "authorized_keys".
ls -al ~/.ssh/
If you're having trouble with this part, you can reference this tutorial which breaks this component into smaller steps: SSH Automatic Login.
Install SSHFS
sudo apt-get install sshfs
Or use whatever package manager your distribution provides.
Mount
Create a shell script, we'll call it "mount.sh", and add the contents:
sshfs [user]@[your_server].com:/dir/on/server /dir/to/mount
Run the script:
./mount.sh
Go to the mounted directory and run the 'ls' command to make sure all of your files/folders from your server show up in your local directory.
After you have this successfully working you should at it to your startup scripts.
System >> Preferences >> Sessions >> [add_a_new_entry]
You should be all set. You should have an automatic SSH login (no prompt for a password) from your computer to your server and a mounted folder to your server that acts as an automatic FTP client. The files in your mounted directory should be synced with that of your server. Now all you have to do is move or copy your desired files/folders into the mounted directory, and voila, they're on your server.
- MySQL University: Boosting Performance With MySQL 5.1 Partitioning - by
It's been some time some time since we had a MySQL Uni session subject that could be interesting to an 'average' PHP developer. The one that's going to take place next Thursday will definitely be of this sort.
Introduced in MySQL 5.1, partitioning lets you divide your tables into smaller chunks of data... while still keeping them in one table. No more need for `invoices2006`, `invoices2007`, `invoices2008` tables to cope with archival data, no more wicked UNIONs. Now you can tell MySQL to keep invoices (or whatever you need to keep) from one year separate from all other years, thus improving queries that only deal with records from one year.
That's just a simple example, as there are much more to partitioning than that. I urge you therefore to attend MySQL Uni's Dimdim session this Thursday, June 4th at 13:00GMT.
The session will be presented by Giuseppe Maxia a.k.a. The Data Charmer. I attended one of his sessions in the past, and he seems like a very interesting person to listen to.
Check the MySQL University home page for details (and possible last minute schedule changes!)
For more information about MySQL University, see my introductory post - or die() must die - by
This is something I constantly see on the PHP Freaks forums, and I absolutely hate it. It's the infamous or die() statement.
- $result = mysql_query('SELECT foo FROM bar', $db) or die('Query failed: ' . mysql_error($db));
I see it all the time, and I see people telling other people to do that all the time. It's plain simply bad practice and it's time that people start to understand this. When I confront people with it they usually say something along the lines of "oh, but it's just for debugging purposes". Okay, so I tend to put echo and var_dump() statements in my code for debugging as well. However, this is not the same. It's quite obvious that you wouldn't want an array var_dump'ed to the screen in the final application, but you certainly do want some sort of error handling for when e.g. database queries fail.
The or die() trick is a very poor choice for several reasons:
- It's not a very nice way to present the user with an error message.
- Using for instance the mysql_error() call with it, as many people do, exposes information that should never get output in a production environment (see: PHP Security)
- You cannot catch the error in any way.
- You cannot log the error.
- You cannot control whether it should be output to the screen or not. It's okay to do that in a development environment, but certainly not in a production environment.
- It prevents you from doing any sort of cleanup. It just ends the script abruptly.
So if your little or die() trick is just for debugging purposes, how are you going to handle potential errors after you've deployed your application? Fortunately, PHP does actually include a function that allows you to raise PHP errors on runtime: trigger_error()
This function allows you to raise errors of type E_USER_NOTICE, E_USER_WARNING and E_USER_ERROR. These behave exactly like their non-USER counterparts, i.e. errors of type E_USER_ERROR are fatal and halts execution while the other two doesn't. If you are used to doing the or die() it's also very easy to implement:
- $result = mysql_query('SELECT foo FROM bar', $db) or trigger_error('Query failed: ' . mysql_error($db), E_USER_ERROR);
Syntactically this is very much like the previous code snippet, but much better. Because errors of these types behave like errors PHP would normally make you can also use all the facilities PHP has for error handling. You can implement a custom error handler so you can display nice messages to your user, and you can log the errors to a file. Finally you can disable output of errors in a production environment.
Another option is to use exceptions. Example:
- if (!$result = mysql_query('SELECT foo FROM bar', $db)) {
- throw new Exception('You fail: ' . mysql_error($db));
- }
Personally, I prefer exceptions because they're easily catchable using try-catch blocks, which makes it pretty easy to degrade if something unexpected, or rather an exception, something that doesn't behave as expected, occurs. As an added bonus you you will get a stack trace which aids in debugging.
A great example of exception usage could be database transactions using PDO (MySQLi supports it as well if you prefer that). When you normally run a query on a database server it will be committed instantaneously. When you start a transaction changes won't be committed until you explicitly say so. This allows you to rollback if you wish.
We might have a setup like this:
+---------+------------+-----------+-------+ | user_id | first_name | last_name | funds | +---------+------------+-----------+-------+ | 1 | Daniel | Egeberg | 500 | | 2 | John | Doe | 350 | +---------+------------+-----------+-------+
We want to transfer 120 from Daniel to John. This involves two operations: 1) Removing funds from Daniel, and 2) Adding funds to John. We need both or none of those operations to finish successfully. Executing just one of them is not an acceptable scenario.
Here is our transfer script:
- $db = new PDO('mysql:host=localhost;dbname=test', 'user', 'password');
- $transferAmount = 120;
- $fromUserId = 1;
- $toUserId = 2;
- try {
- $db->beginTransaction();
- $stmt = $db->prepare('UPDATE users SET funds = funds + :amount WHERE user_id = :user_id');
- // remove funds from sender
- $stmt->execute(array('amount' => $transferAmount * -1, 'user_id' => $fromUserId));
- // add funds to recipient
- $stmt->execute(array('amount' => $transferAmount, 'user_id' => $toUserId));
- $db->commit(); // we will only get to this if both the above queries executed successfully
- }
- catch (PDOException $e) {
- $db->rollback(); // damn... well, at least we can roll back
- echo 'Sorry, but we were unable to transfer the funds. Please contact customer support if the problem persists.';
- // log this incident somehow. further info is available using $e->getMessage()
- }
Finally just a quick check that we did in fact transfer the money:
+---------+------------+-----------+-------+ | user_id | first_name | last_name | funds | +---------+------------+-----------+-------+ | 1 | Daniel | Egeberg | 380 | | 2 | John | Doe | 470 | +---------+------------+-----------+-------+
Yup. Everything's good!
In this case our good friend or die() is simply not an option. If the first statement ran fine, but the second failed I would have just lost money on nothing, and because the programmer was too lazy to implement real error handling nobody would be able to figure out what happened, and the case couldn't be documented. I certainly would not appreciate that...
People need to stop that or die() nonsense, and even more importantly, people need to stop teaching other people their own bad practice. Calling die() when something happens is not an acceptable way of handling the situation.

