Tuesday, January 10, 2017

PHP and MySQL Basics

PHP and MySQL have had a long intertwined path together. I have been talking with a lot of newbies in the past several months who are trying to become PHP developers but are amazed at all the ancillary parts that go along with PHP such as unit testing, databases, JavaScript, continuous integration, and much more. Add in that there are two MySQL APIs -- PDO & MySQLi -- and an older deprecated mysql API still often found in the wild. This blog is the start of a series for new PHP developers to learn to program with a database.

Client Server Model

The PHP code when it seeks to talk to a MySQL (or most other databases) will make a connection to a port at an IP address. Usually MySQL is listening on port 3306. If you are developing an accessing a database on your local computer the IP address used will generally be at 127.0.0.1. The software that goes between the PHP application and the database is called a connector.

So your code on you local system an be talking to a database server on your local system or through a network connection. It does not matter which.

Can't connect to MySQL server on 'x.x.x.x' (111)

The Can't connect error can be especially frustrating. An experienced developer will know what to check from tears of experience. But this is a column on basics so we need to spell out the steps.
  1. Is the IP address correct? It is easy to fat finger IP address and ironically 127.0.01 on many Linux boxes will connect up to 127.0.0.1.
  2. Is there a instance of MySQL running at that IP address?
  3. Is that instance listening on the generic port 3306? Is may be running someplace else and you will have to chance down that port number.
  4. Can the MySQL command line shell or other tool connect to the instance? MySQL Workbench, PhPMyAdmin, the cli tools, and everything else authenticate through the same steps so if they work and your PHP program does not then most likely the fault is in the PHP code.

Setting up the client server connection

The PHP Manual is worth its weight in gold and you should refer to it often. Its examples are clear, or usually as clear as can be, and concise. Below is an excerpt example from the manual.

<?php

$mysqli = new mysqli("127.0.0.1", "user", "password", "database", 3306);
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

echo $mysqli->host_info . "\n";
?>

Note that the IP address, user name of "user", password of "password", and the port of 3306 will need to be changed to fit the installation. The mysqli call sets up the connection between the application and the MySQL database server.

Please note that you should protect usernames and password or any other information that could allow someone to compromise the server and data.

The if statement is invoked when there is an error code is returned from the $mysql->connect_errono call. Subsequently the error message from the server can be printed out using $mysqli->error. The error message itself can be terse but often points out what is wrong in the code.

Bad arguments

What follows below are three bad connection strings.
// Bad IP address
$mysqli = new mysqli("19.10.0.3", "root", "barfoo", "world_x", 3306);
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

// Bad account information
$mysqli = new mysqli("127.0.0.1", "root", "foobar", "world_x", 3306);
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

// Bad database specified
$mysqli = new mysqli("127.0.0.1", "root", "foobar", "world_xx\", 3306);
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

Part of mastering any computer programming language is learning to understand the error messages. The three examples above return similar but distinctly different messages.

The first of the trip provides the following error:


PHP Warning:  mysqli::__construct(): (HY000/2002): Network is unreachable in /home/dstokes/php/m02.php 
Failed to connect to MySQL: (2002) Network is unreachable

It would be nice to get more information than 'Network in unreachable' but it provides a starting point to diagnose the problem. Generally the more specific the problem, the more specific the error message.

The third of the trio attempts to connect to a database named 'world_xx' when we really wanted 'world_x'.

PHP Warning:  mysqli::__construct(): (HY000/1049): Unknown database 'world_xx' in /home/dstokes/php/m02.php
Failed to connect to MySQL: (1049) Unknown database 'world_xx'

Sadly for beginners it takes time and experience to get to the point where you can instantly look at an error and know what has gone wrong (or have a pretty good idea of what has gone wrong). But do not worry as many of us learn by correcting OUR mistakes and learning not to repeat them.

Connection Good

So after establishing a good connection to the MySQL server, we can now query it for data.
Next Time -- what happened to my query??