From f3db6b7ad48f2ba44d7176fbc2ace8bf21d64c8d Mon Sep 17 00:00:00 2001 From: jrfnl Date: Mon, 8 Dec 2014 23:52:46 +0100 Subject: [PATCH] Fix menu inconsistencies - Chapter 7 --- _posts/07-01-01-Databases.md | 87 ------------------- _posts/07-02-01-Databases_MySQL.md | 28 ++++++ _posts/07-03-01-Databases_PDO.md | 74 ++++++++++++++++ ...de.md => 07-04-01-Interacting-via-Code.md} | 0 ...yers.md => 07-05-01-Abstraction-Layers.md} | 0 5 files changed, 102 insertions(+), 87 deletions(-) create mode 100644 _posts/07-02-01-Databases_MySQL.md create mode 100644 _posts/07-03-01-Databases_PDO.md rename _posts/{07-02-01-Interacting-via-Code.md => 07-04-01-Interacting-via-Code.md} (100%) rename _posts/{07-03-01-Abstraction-Layers.md => 07-05-01-Abstraction-Layers.md} (100%) diff --git a/_posts/07-01-01-Databases.md b/_posts/07-01-01-Databases.md index fbfef59..362e11f 100644 --- a/_posts/07-01-01-Databases.md +++ b/_posts/07-01-01-Databases.md @@ -13,94 +13,7 @@ Native drivers are great if you are only using _one_ database in your applicatio MySQL and a little bit of MSSQL, or you need to connect to an Oracle database, then you will not be able to use the same drivers. You'll need to learn a brand new API for each database — and that can get silly. -## MySQL Extension -The [mysql] extension for PHP is no longer in active development, and is [officially deprecated as of PHP 5.5.0] -[mysql_deprecated], meaning that it will be removed within the next few releases. If you are using any functions that -start with `mysql_*` such as `mysql_connect()` and `mysql_query()` in your applications then these will simply not be -available in later versions of PHP. This means you will be faced with a rewrite at some point down the line, so the -best option is to replace mysql usage with [mysqli] or [PDO] in your applications within your own development schedules -so you won't be rushed later on. - -**If you are starting from scratch then absolutely do not use the [mysql] extension: use the [MySQLi extension][mysqli], -or use [PDO].** - -* [PHP: Choosing an API for MySQL][mysql_api] -* [PDO Tutorial for MySQL Developers][pdo4mysql_devs] - -## PDO Extension - -[PDO] is a database connection abstraction library — built into PHP since 5.1.0 — that provides a common -interface to talk with many different databases. For example, you can use basically identical code to interface with -MySQL or SQLite: - -{% highlight php %} -query("SELECT some\_field FROM some\_table"); -$row = $statement->fetch(PDO::FETCH_ASSOC); -echo htmlentities($row['some_field']); - -// PDO + SQLite -$pdo = new PDO('sqlite:/path/db/foo.sqlite'); -$statement = $pdo->query("SELECT some\_field FROM some\_table"); -$row = $statement->fetch(PDO::FETCH_ASSOC); -echo htmlentities($row['some_field']); -{% endhighlight %} - -PDO will not translate your SQL queries or emulate missing features; it is purely for connecting to multiple types of -database with the same API. - -More importantly, `PDO` allows you to safely inject foreign input (e.g. IDs) into your SQL queries without worrying -about database SQL injection attacks. -This is possible using PDO statements and bound parameters. - -Let's assume a PHP script receives a numeric ID as a query parameter. This ID should be used to fetch a user record -from a database. This is the `wrong` way to do this: - -{% highlight php %} -query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NO! -{% endhighlight %} - -This is terrible code. You are inserting a raw query parameter into a SQL query. This will get you hacked in a -heartbeat, using a practice called [SQL Injection]. Just imagine if a hacker passes in an inventive `id` parameter by -calling a URL like `http://domain.com/?id=1%3BDELETE+FROM+users`. This will set the `$_GET['id']` variable to `1;DELETE -FROM users` which will delete all of your users! Instead, you should sanitize the ID input using PDO bound parameters. - -{% highlight php %} -prepare('SELECT name FROM users WHERE id = :id'); -$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); // <-- Automatically sanitized by PDO -$stmt->execute(); -{% endhighlight %} - -This is correct code. It uses a bound parameter on a PDO statement. This escapes the foreign input ID before it is -introduced to the database preventing potential SQL injection attacks. - -* [Learn about PDO] - -You should also be aware that database connections use up resources and it was not unheard-of to have resources -exhausted if connections were not implicitly closed, however this was more common in other languages. Using PDO you can -implicitly close the connection by destroying the object by ensuring all remaining references to it are deleted, i.e. -set to NULL. If you don't do this explicitly, PHP will automatically close the connection when your script ends - -unless of course you are using persistent connections. - -* [Learn about PDO connections] - - -[mysql_deprecated]: http://php.net/migration55.deprecated -[mysql_api]: http://php.net/mysqlinfo.api.choosing -[pdo4mysql_devs]: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers -[SQL Injection]: http://wiki.hashphp.org/Validation -[Learn about PDO]: http://php.net/book.pdo -[Learn about PDO connections]: http://php.net/pdo.connections - -[pdo]: http://php.net/pdo -[mysql]: http://php.net/mysql [mysqli]: http://php.net/mysqli [pgsql]: http://php.net/pgsql [mssql]: http://php.net/mssql diff --git a/_posts/07-02-01-Databases_MySQL.md b/_posts/07-02-01-Databases_MySQL.md new file mode 100644 index 0000000..362cd88 --- /dev/null +++ b/_posts/07-02-01-Databases_MySQL.md @@ -0,0 +1,28 @@ +--- +isChild: true +title: MySQL Extension +anchor: mysql_extension +--- + +## MySQL Extension {#mysql_extension_title} + +The [mysql] extension for PHP is no longer in active development, and is [officially deprecated as of PHP 5.5.0] +[mysql_deprecated], meaning that it will be removed within the next few releases. If you are using any functions that +start with `mysql_*` such as `mysql_connect()` and `mysql_query()` in your applications then these will simply not be +available in later versions of PHP. This means you will be faced with a rewrite at some point down the line, so the +best option is to replace mysql usage with [mysqli] or [PDO] in your applications within your own development schedules +so you won't be rushed later on. + +**If you are starting from scratch then absolutely do not use the [mysql] extension: use the [MySQLi extension][mysqli], +or use [PDO].** + +* [PHP: Choosing an API for MySQL][mysql_api] +* [PDO Tutorial for MySQL Developers][pdo4mysql_devs] + + +[mysql]: http://php.net/mysql +[mysql_deprecated]: http://php.net/migration55.deprecated +[mysqli]: http://php.net/mysqli +[pdo]: http://php.net/pdo +[mysql_api]: http://php.net/mysqlinfo.api.choosing +[pdo4mysql_devs]: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers diff --git a/_posts/07-03-01-Databases_PDO.md b/_posts/07-03-01-Databases_PDO.md new file mode 100644 index 0000000..739b605 --- /dev/null +++ b/_posts/07-03-01-Databases_PDO.md @@ -0,0 +1,74 @@ +--- +isChild: true +title: PDO Extension +anchor: pdo_extension +--- + +## PDO Extension {#pdo_extension_title} + +[PDO] is a database connection abstraction library — built into PHP since 5.1.0 — that provides a common +interface to talk with many different databases. For example, you can use basically identical code to interface with +MySQL or SQLite: + +{% highlight php %} +query("SELECT some\_field FROM some\_table"); +$row = $statement->fetch(PDO::FETCH_ASSOC); +echo htmlentities($row['some_field']); + +// PDO + SQLite +$pdo = new PDO('sqlite:/path/db/foo.sqlite'); +$statement = $pdo->query("SELECT some\_field FROM some\_table"); +$row = $statement->fetch(PDO::FETCH_ASSOC); +echo htmlentities($row['some_field']); +{% endhighlight %} + +PDO will not translate your SQL queries or emulate missing features; it is purely for connecting to multiple types of +database with the same API. + +More importantly, `PDO` allows you to safely inject foreign input (e.g. IDs) into your SQL queries without worrying +about database SQL injection attacks. +This is possible using PDO statements and bound parameters. + +Let's assume a PHP script receives a numeric ID as a query parameter. This ID should be used to fetch a user record +from a database. This is the `wrong` way to do this: + +{% highlight php %} +query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NO! +{% endhighlight %} + +This is terrible code. You are inserting a raw query parameter into a SQL query. This will get you hacked in a +heartbeat, using a practice called [SQL Injection]. Just imagine if a hacker passes in an inventive `id` parameter by +calling a URL like `http://domain.com/?id=1%3BDELETE+FROM+users`. This will set the `$_GET['id']` variable to `1;DELETE +FROM users` which will delete all of your users! Instead, you should sanitize the ID input using PDO bound parameters. + +{% highlight php %} +prepare('SELECT name FROM users WHERE id = :id'); +$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); // <-- Automatically sanitized by PDO +$stmt->execute(); +{% endhighlight %} + +This is correct code. It uses a bound parameter on a PDO statement. This escapes the foreign input ID before it is +introduced to the database preventing potential SQL injection attacks. + +* [Learn about PDO] + +You should also be aware that database connections use up resources and it was not unheard-of to have resources +exhausted if connections were not implicitly closed, however this was more common in other languages. Using PDO you can +implicitly close the connection by destroying the object by ensuring all remaining references to it are deleted, i.e. +set to NULL. If you don't do this explicitly, PHP will automatically close the connection when your script ends - +unless of course you are using persistent connections. + +* [Learn about PDO connections] + + +[pdo]: http://php.net/pdo +[SQL Injection]: http://wiki.hashphp.org/Validation +[Learn about PDO]: http://php.net/book.pdo +[Learn about PDO connections]: http://php.net/pdo.connections diff --git a/_posts/07-02-01-Interacting-via-Code.md b/_posts/07-04-01-Interacting-via-Code.md similarity index 100% rename from _posts/07-02-01-Interacting-via-Code.md rename to _posts/07-04-01-Interacting-via-Code.md diff --git a/_posts/07-03-01-Abstraction-Layers.md b/_posts/07-05-01-Abstraction-Layers.md similarity index 100% rename from _posts/07-03-01-Abstraction-Layers.md rename to _posts/07-05-01-Abstraction-Layers.md