SlideShare una empresa de Scribd logo
1 de 81
Descargar para leer sin conexión
PHP 102 Out with the Bad, In with the Good Memphis PHP, February 23, 2012
Who is this guy? ,[object Object]
Following Along ,[object Object]
Why Did You  Start Programming?
I wanted to solve problems, but . . .
. . . I frequently caused  as many problems  as I solved.
Let's Solve a Problem Together ,[object Object]
Make horrible mistakes
Correct those mistakes
Make a cool improvement
Learn something?
What's the Problem? ,[object Object]
Requirements: ,[object Object]
Add books
Edit books
Delete books ,[object Object]
So, What do we Need? ,[object Object]
View (index.php)
Form (book-form.php)
Form processor (process-form.php)
index.php – db connection <?php $db   =   realpath ( dirname ( __FILE__ )  .   '/data/db/bookshelf.db' ); $dsn   =   &quot;sqlite: $db &quot; ; $options   =   array (   PDO :: ATTR_ERRMODE   =>   PDO :: ERRMODE_EXCEPTION ,   PDO :: ATTR_DEFAULT_FETCH_MODE   =>   PDO :: FETCH_ASSOC ); try  {   $dbh   =   new   PDO ( $dsn ,  null ,  null ,  $options ); }  catch  ( PDOException   $e ) {   echo   &quot;Error!: &quot;   .   $e -> getMessage()  .   &quot;<br />  &quot; ;   die (); } $books   =   $dbh -> query( &quot; SELECT   *   FROM  bookshelf  ORDER BY  title&quot; ) -> fetchAll();
index.php – db connection <?php $db   =   realpath ( dirname ( __FILE__ )  .   '/data/db/bookshelf.db' ); $dsn   =   &quot;sqlite: $db &quot; ; $options   =   array (   PDO :: ATTR_ERRMODE   =>   PDO :: ERRMODE_EXCEPTION ,   PDO :: ATTR_DEFAULT_FETCH_MODE   =>   PDO :: FETCH_ASSOC ); try  {   $dbh   =   new   PDO ($dsn,  null ,  null , $options); }  catch  ( PDOException   $e) {   echo   &quot;Error!: &quot;   .   $e -> getMessage()  .   &quot;<br />&quot;;   die (); } $books   =   $dbh -> query(&quot; SELECT   *   FROM  bookshelf  ORDER BY  title&quot;) -> fetchAll() ;
index.php – db connection <?php $db   =   realpath ( dirname ( __FILE__ )  .   '/data/db/bookshelf.db'); $dsn   =   &quot;sqlite:$db&quot;; $options   =   array (   PDO::ATTR_ERRMODE   =>   PDO::ERRMODE_EXCEPTION ,   PDO::ATTR_DEFAULT_FETCH_MODE   =>   PDO::FETCH_ASSOC ); try  {   $dbh   =   new   PDO ( $dsn ,  null ,  null ,  $options ); }  catch  ( PDOException   $e ) {   echo   &quot;Error!: &quot;   .   $e -> getMessage()  .   &quot;<br />  &quot; ;   die (); } $books   =   $dbh -> query(&quot; SELECT   *   FROM  bookshelf  ORDER BY  title&quot;) -> fetchAll();
index.php – db connection <?php $db   =   realpath ( dirname ( __FILE__ )  .   '/data/db/bookshelf.db'); $dsn   =   &quot;sqlite:$db&quot;; $options   =   array (   PDO::ATTR_ERRMODE   =>   PDO::ERRMODE_EXCEPTION ,   PDO::ATTR_DEFAULT_FETCH_MODE   =>   PDO::FETCH_ASSOC ); try  {   $dbh   =   new   PDO ($dsn,  null ,  null , $options); }  catch  ( PDOException   $e) {   echo   &quot;Error!: &quot;   .   $e -> getMessage()  .   &quot;<br />&quot;;   die (); } $books   =   $dbh -> query( &quot; SELECT   *   FROM  bookshelf  ORDER BY  title&quot; ) -> fetchAll();
index.php
index.php – books table <?php  if  ( count ( $books )  >   0 ): ?>   < table >   < tr >   < th > Title </ th >< th > Author </ th >   </ tr >   <?php  foreach  ( $books   as   $book ): ?>   < tr >   < td >   < a   href= &quot;book-form.php?id=<?php   echo   $book ['id'];   ?>&quot; >   <?php   echo   $book [ 'title' ];   ?>   </ a >   </ td >   < td >   <?php   echo   $book [ 'author' ];   ?>   </ td >   </ tr >   <?php  endforeach ;   ?>   </ table > <?php  else : ?>   < p > We have no books! </ p > <?php  endif ;   ?>
index.php – books table <?php  if  ( count ( $books )  >   0 ): ?>   < table >   < tr >   < th > Title </ th >< th > Author </ th >   </ tr >   <?php  foreach  ( $books   as   $book ): ?>   < tr >   < td >   < a   href= &quot;book-form.php?id=<?php   echo   $book ['id'];   ?>&quot; >   <?php   echo   $book [ 'title' ];   ?>   </ a >   </ td >   < td >   <?php   echo   $book [ 'author' ];   ?>   </ td >   </ tr >   <?php  endforeach ;   ?>   </ table > <?php  else : ?>   < p >We have no books!</ p > <?php  endif ; ?>
index.php – books table <?php  if  ( count ($books)  >  0): ?>   < table >   < tr >   < th >Title</ th >< th >Author</ th >   </ tr >   <?php  foreach  ( $books   as   $book ): ?>   < tr >   < td >   < a   href= &quot;book-form.php?id=<?php   echo   $book ['id'];   ?>&quot; >   <?php   echo   $book [ 'title' ];   ?>   </ a >   </ td >   < td >   <?php   echo   $book [ 'author' ];   ?>   </ td >   </ tr >   <?php  endforeach ;   ?>   </ table > <?php  else : ?>   < p >We have no books!</ p > <?php  endif ; ?>
index.php – books table <?php  if  ( count ($books)  >  0): ?>   < table >   < tr >   < th >Title</ th >< th >Author</ th >   </ tr >   <?php  foreach  ($books  as  $book): ?>   < tr >   < td >   < a  href=&quot;book-form.php?id=<?php  echo  $book['id']; ?>&quot;>   <?php  echo  $book['title']; ?>   </ a >   </ td >   < td >   <?php  echo  $book['author']; ?>   </ td >   </ tr >   <?php  endforeach ; ?>   </ table > <?php  else : ?>   < p > We have no books! </ p > <?php  endif ;   ?>
 
book-form.php
book-form.php <?php $id   =   empty ( $_GET [ 'id' ]) ?  null  :  $_GET [ 'id' ]; if  ( $id ) {   // Database connection code   $book   =   $dbh -> query( &quot; SELECT  title, author  FROM  bookshelf  WHERE  id  =   $id &quot; ) -> fetch();   $title   =   $book [ 'title' ];   $author   =   $book [ 'author' ]; }
book-form.php <?php $id   =   empty ( $_GET [ 'id' ]) ?  null  :  $_GET [ 'id' ]; if  ($id) {   // Database connection code   $book  =  $dbh -> query(&quot; SELECT  title, author  FROM  bookshelf  WHERE  id  =  $id&quot;) -> fetch();   $title  =  $book['title'];   $author  =  $book['author']; }
book-form.php <?php $id  =   empty ($_GET['id']) ?  null  : $_GET['id']; if  ( $id ) {   // Database connection code   $book   =   $dbh -> query( &quot; SELECT  title, author  FROM  bookshelf  WHERE  id  =   $id &quot; ) -> fetch();   $title   =   $book [ 'title' ];   $author   =   $book [ 'author' ]; }
book-form.php < form   method= &quot;post&quot;   action= &quot;process-book.php&quot; >   < input   type= &quot;hidden&quot;   id= &quot;id&quot;   name= &quot;id&quot;   value= &quot;<?php   echo   $id ;   ?>&quot;  />   < dl >   < dt >   < label   for= &quot;title&quot; > Title </ label >   </ dt >   < dd >   < input   type= &quot;text&quot;   id= &quot;title&quot;   name= &quot;title&quot;   value= &quot;<?php   echo   $title ;   ?>&quot;  />   </ dd >   < dt >   < label   for= &quot;author&quot; > Author </ label >   </ dt >   < dd >   < input   type= &quot;text&quot;   id= &quot;author&quot;   name= &quot;author&quot;   value= &quot;<?php   echo   $author ;   ?>&quot;  />   </ dd >   < dt > &nbsp; </ dt >   < dd >   < input   type= &quot;submit&quot;   value= &quot;Submit&quot;  />   </ dd >   </ dl > </ form >
book-form.php < form   method= &quot;post&quot;   action= &quot;process-book.php&quot; >   < input  type=&quot;hidden&quot; id=&quot;id&quot; name=&quot;id&quot;  value= &quot;<?php   echo   $id ;   ?>&quot;  />   < dl >   < dt >   < label  for=&quot;title&quot;>Title</ label >   </ dt >   < dd >   < input  type=&quot;text&quot; id=&quot;title&quot; name=&quot;title&quot;  value= &quot;<?php   echo   $title ;   ?>&quot;  />   </ dd >   < dt >   < label  for=&quot;author&quot;>Author</ label >   </ dt >   < dd >   < input  type=&quot;text&quot; id=&quot;author&quot; name=&quot;author&quot;  value= &quot;<?php   echo   $author ;   ?>&quot;  />   </ dd >   < dt > &nbsp; </ dt >   < dd >   < input  type=&quot;submit&quot; value=&quot;Submit&quot; />   </ dd >   </ dl > </ form >
process-book.php <?php if  ( strtolower ( $_SERVER [ 'REQUEST_METHOD' ])  ==   'get' ) {   header ( &quot;Location: /&quot; ); } // Database connection code if  ( empty ( $_POST [ 'id' ])) {   $sql   =   &quot; INSERT INTO  bookshelf (title, author) &quot;   . &quot;VALUES ('{ $_POST ['title']}', '{ $_POST ['author']}')&quot; ;   $dbh -> exec( $sql ); }  else  {   $sql   =   &quot; UPDATE  bookshelf  SET  title  =   '{ $_POST ['title']}', &quot;   .   &quot;author = '{ $_POST ['author']}' WHERE id = { $_POST ['id']}&quot; ;   $dbh -> exec( $sql ); } header ( &quot;Location: /&quot; );
process-book.php <?php if  ( strtolower ( $_SERVER [ 'REQUEST_METHOD' ])  ==   'get' ) {   header ( &quot;Location: /&quot; ); } // Database connection code if  ( empty ($_POST['id'])) {   $sql  =  &quot; INSERT INTO  bookshelf (title, author) &quot;   . &quot;VALUES ('{$_POST['title']}', '{$_POST['author']}')&quot;;   $dbh -> exec($sql); }  else  {   $sql  =  &quot; UPDATE  bookshelf  SET  title  =  '{$_POST['title']}', &quot;   .  &quot;author = '{$_POST['author']}' WHERE id = {$_POST['id']}&quot;;   $dbh -> exec($sql); } header (&quot;Location: /&quot;);
process-book.php <?php if  ( strtolower ($_SERVER['REQUEST_METHOD'])  ==  'get') {   header (&quot;Location: /&quot;); } // Database connection code if  ( empty ($_POST['id'])) {   $sql  =  &quot; INSERT INTO  bookshelf (title, author) &quot;   . &quot;VALUES ('{$_POST['title']}', '{$_POST['author']}')&quot;;   $dbh -> exec($sql); }  else  {   $sql  =  &quot; UPDATE  bookshelf  SET  title  =  '{$_POST['title']}', &quot;   .  &quot;author = '{$_POST['author']}' WHERE id = {$_POST['id']}&quot;;   $dbh -> exec($sql); } header (&quot;Location: /&quot;);
process-book.php <?php if  ( strtolower ($_SERVER['REQUEST_METHOD'])  ==  'get') {   header (&quot;Location: /&quot;); } // Database connection code if  ( empty ( $_POST [ 'id' ])) {   $sql   =   &quot; INSERT INTO  bookshelf (title, author) &quot;   . &quot;VALUES ('{ $_POST ['title']}', '{ $_POST ['author']}')&quot; ;   $dbh -> exec( $sql ); }   else  {   $sql  =  &quot; UPDATE  bookshelf  SET  title  =  '{$_POST['title']}', &quot;   .  &quot;author = '{$_POST['author']}' WHERE id = {$_POST['id']}&quot;;   $dbh -> exec($sql); } header (&quot;Location: /&quot;);
process-book.php <?php if  ( strtolower ($_SERVER['REQUEST_METHOD'])  ==  'get') {   header (&quot;Location: /&quot;); } // Database connection code if  ( empty ($_POST['id'])) {   $sql  =  &quot; INSERT INTO  bookshelf (title, author) &quot;   . &quot;VALUES ('{$_POST['title']}', '{$_POST['author']}')&quot;;   $dbh -> exec($sql); }   else  {   $sql   =   &quot; UPDATE  bookshelf  SET  title  =   '{ $_POST ['title']}', &quot;   .   &quot;author = '{ $_POST ['author']}' WHERE id = { $_POST ['id']}&quot; ;   $dbh -> exec( $sql ); } header (&quot;Location: /&quot;);
process-book.php <?php if  ( strtolower ($_SERVER['REQUEST_METHOD'])  ==  'get') {   header (&quot;Location: /&quot;); } // Database connection code if  ( empty ($_POST['id'])) {   $sql  =  &quot; INSERT INTO  bookshelf (title, author) &quot;   . &quot;VALUES ('{$_POST['title']}', '{$_POST['author']}')&quot;;   $dbh -> exec($sql); }  else  {   $sql  =  &quot; UPDATE  bookshelf  SET  title  =  '{$_POST['title']}', &quot;   .  &quot;author = '{$_POST['author']}' WHERE id = {$_POST['id']}&quot;;   $dbh -> exec($sql); } header ( &quot;Location: /&quot; );
Glaring Problems? ,[object Object]
Input isn't filtered
Output isn't escaped
User-provided data used in SQL
Code Duplication try  {   $dbh   =   new   PDO ( $dsn ,  null ,  null ,  $options ); }  catch  ( PDOException   $e ) {   echo   &quot;Error!: &quot;   .   $e -> getMessage()  .   &quot;<br />  &quot; ;   die (); } ,[object Object]
Maintenance nightmare
The next developer will want to kill you
And your family
And your pets
Consolidate ,[object Object]
base.php <?php date_default_timezone_set ('America/Chicago'); error_reporting ( - 1); ini_set ('display_errors', 1); ini_set ('display_startup_errors', 1); $db   =   realpath ( dirname ( __FILE__ )  .   '/../data/db/bookshelf.db' ); $dsn   =   &quot;sqlite: $db &quot; ; $options   =   array (   PDO :: ATTR_ERRMODE   =>   PDO :: ERRMODE_EXCEPTION ,   PDO :: ATTR_DEFAULT_FETCH_MODE   =>   PDO :: FETCH_ASSOC ); try  {   $dbh   =   new   PDO ( $dsn ,  null ,  null ,  $options ); }  catch  ( PDOException   $e ) {   throw   $e ;   echo   &quot;Error!: &quot;   .   $e -> getMessage()  .   &quot;<br />  &quot; ;   die (); }
base.php <?php date_default_timezone_set ( 'America/Chicago' ); error_reporting ( - 1); ini_set ('display_errors', 1); ini_set ('display_startup_errors', 1); $db  =   realpath ( dirname ( __FILE__ )  .  '/../data/db/bookshelf.db'); $dsn  =  &quot;sqlite:$db&quot;; $options  =   array (   PDO::ATTR_ERRMODE   =>   PDO::ERRMODE_EXCEPTION ,   PDO::ATTR_DEFAULT_FETCH_MODE   =>   PDO::FETCH_ASSOC ); try  {   $dbh  =   new   PDO ($dsn,  null ,  null , $options); }  catch  ( PDOException  $e) {   throw  $e;   echo  &quot;Error!: &quot;  .  $e -> getMessage()  .  &quot;<br />&quot;;   die (); }
base.php <?php date_default_timezone_set ('America/Chicago'); error_reporting ( - 1 ); ini_set ( 'display_errors' ,  1 ); ini_set ( 'display_startup_errors' ,  1 ); $db  =   realpath ( dirname ( __FILE__ )  .  '/../data/db/bookshelf.db'); $dsn  =  &quot;sqlite:$db&quot;; $options  =   array (   PDO::ATTR_ERRMODE   =>   PDO::ERRMODE_EXCEPTION ,   PDO::ATTR_DEFAULT_FETCH_MODE   =>   PDO::FETCH_ASSOC ); try  {   $dbh  =   new   PDO ($dsn,  null ,  null , $options); }  catch  ( PDOException  $e) {   throw  $e;   echo  &quot;Error!: &quot;  .  $e -> getMessage()  .  &quot;<br />&quot;;   die (); }
Replace db info with base.php ,[object Object],require_once   dirname ( __FILE__ )   .   '/library/base.php' ;
Duplication removed, but . . .
 
We echo $title and $author < form  method=&quot;post&quot; action=&quot;process-book.php&quot;>   < input  type=&quot;hidden&quot; id=&quot;id&quot; name=&quot;id&quot; value=&quot;<?php  echo  $id; ?>&quot; />   < dl >   < dt >   < label  for=&quot;title&quot;>Title</ label >   </ dt >   < dd >   < input  type=&quot;text&quot; id=&quot;title&quot; name=&quot;title&quot;  value= &quot;<?php   echo   $title ;   ?>&quot;  />   </ dd >   < dt >   < label  for=&quot;author&quot;>Author</ label >   </ dt >   < dd >   < input  type=&quot;text&quot; id=&quot;author&quot; name=&quot;author&quot;  value= &quot;<?php   echo   $author ;   ?>&quot;  />   </ dd >   < dt > &nbsp; </ dt >   < dd >   < input  type=&quot;submit&quot; value=&quot;Submit&quot; />   </ dd >   </ dl > </ form >
Without defining $title and $author require_once   dirname ( __FILE__ )   .   '/library/base.php' ; $id   =   empty ( $_GET [ 'id' ]) ?  null  :  $_GET [ 'id' ]; if  ( $id ) {   $book   =   $dbh -> query( . . . ) -> fetch();   $title   =   $book [ 'title' ];   $author   =   $book [ 'author' ]; }
Super easy to fix require_once   dirname ( __FILE__ )  .  '/library/base.php'; $id  =   empty ($_GET['id']) ?  null  : $_GET['id']; $title   =   null ; $author   =   null ; if  ($id) {   $book  =  $dbh -> query( . . . ) -> fetch();   $title  =  $book['title'];   $author  =  $book['author']; }
FIEO ,[object Object]
Prevent SQL injection ,[object Object],[object Object]
Defend against XSS
http://xkcd.com/327/
book-form.php ,[object Object],$id   =   filter_input ( INPUT_GET ,  'id' ,  FILTER_VALIDATE_INT );
process-book.php ,[object Object],$id   =   filter_input ( INPUT_POST ,  'id' ,  FILTER_VALIDATE_INT ); $title   =   filter_input ( INPUT_POST ,  'title' , FILTER_SANITIZE_STRING ); $author   =   filter_input ( INPUT_POST ,  'author' , FILTER_SANITIZE_STRING );
index.php ,[object Object],<?php  foreach  ($books  as  $book): ?> < tr >   < td >   < a  href=&quot;book-form.php?id=<?php  echo  $book['id']; ?>&quot;> <?php   echo   htmlspecialchars ( $book [ 'title' ],  ENT_COMPAT ,  'UTF-8' );   ?>   </ a >   </ td >   < td > <?php   echo   htmlspecialchars ( $book [ 'author' ],  ENT_COMPAT ,  'UTF-8' );   ?>   </ td > </ tr > <?php  endforeach ; ?>
Prepared Statements ,[object Object]
Help protect against SQL injection
Easier to read and maintain
book-form.php: Before $book   =   $dbh -> query( &quot; SELECT  title, author  FROM  bookshelf  WHERE  id  =   $id &quot; ) -> fetch();
book-form.php: After $statement   =   $dbh -> prepare( ' SELECT  title, author  FROM  bookshelf  WHERE  id  =  :id' ); $statement -> bindParam( ':id' ,  $id ); $statement -> execute(); $book   =   $statement -> fetch();
book-form.php: After $statement   =   $dbh -> prepare (' SELECT  title, author  FROM  bookshelf  WHERE  id  =  :id'); $statement -> bindParam(':id', $id); $statement -> execute(); $book  =  $statement -> fetch();
book-form.php: After $statement  =  $dbh -> prepare( ' SELECT  title, author  FROM  bookshelf  WHERE  id  =  :id' ); $statement -> bindParam(':id', $id); $statement -> execute(); $book  =  $statement -> fetch();
book-form.php: After $statement  =  $dbh -> prepare(' SELECT  title, author  FROM  bookshelf  WHERE  id  =  :id'); $statement -> bindParam( ':id' ,  $id ); $statement -> execute(); $book  =  $statement -> fetch();
book-form.php: After $statement  =  $dbh -> prepare(' SELECT  title, author  FROM  bookshelf  WHERE  id  =  :id'); $statement -> bindParam(':id', $id); $statement -> execute(); $book   =   $statement -> fetch();
process-book.php: Before if  ( empty ( $_POST [ 'id' ])) {   $sql   =   &quot; INSERT INTO  bookshelf (title, author) &quot;   . &quot;VALUES ('{ $_POST ['title']}', '{ $_POST ['author']}')&quot; ;   $dbh -> exec( $sql ); }  else  {   $sql   =   &quot; UPDATE  bookshelf  SET  title  =   '{ $_POST ['title']}', &quot;   .   &quot;author = '{ $_POST ['author']}' WHERE id = { $_POST ['id']}&quot; ;   $dbh -> exec( $sql ); }
process-book.php: After if  ( $id ) {   $statement   =   $dbh -> prepare( &quot; UPDATE  bookshelf  SET  title  =  :title, author  =  :author  WHERE  id  =  :id&quot; );   $statement -> bindParam( ':title' ,  $title );   $statement -> bindParam( ':author' ,  $author );   $statement -> bindParam( ':id' ,  $id );   $statement -> execute(); }  else  {   $statement   =   $dbh -> prepare( &quot; INSERT INTO  bookshelf (title, author)  VALUES  (:title, :author)&quot; );   $statement -> bindParam( ':title' ,  $title );   $statement -> bindParam( ':author' ,  $author );   $statement -> execute(); }
process-book.php: After if  ( $id ) {   $statement   =   $dbh -> prepare( &quot; UPDATE  bookshelf  SET  title  =  :title, author  =  :author  WHERE  id  =  :id&quot; );   $statement -> bindParam(':title', $title);   $statement -> bindParam(':author', $author);   $statement -> bindParam(':id', $id);   $statement -> execute(); }  else  {   $statement   =   $dbh -> prepare( &quot; INSERT INTO  bookshelf (title, author)  VALUES  (:title, :author)&quot; );   $statement -> bindParam(':title', $title);   $statement -> bindParam(':author', $author);   $statement -> execute(); }
process-book.php: After if  ($id) {   $statement  =  $dbh -> prepare(&quot; UPDATE  bookshelf  SET  title  =  :title, author  =  :author  WHERE  id  =  :id&quot;);   $statement -> bindParam( ':title' ,  $title );   $statement -> bindParam( ':author' ,  $author );   $statement -> bindParam( ':id' ,  $id );   $statement -> execute(); }  else  {   $statement  =  $dbh -> prepare(&quot; INSERT INTO  bookshelf (title, author)  VALUES  (:title, :author)&quot;);   $statement -> bindParam( ':title' ,  $title );   $statement -> bindParam( ':author' ,  $author );   $statement -> execute(); }

Más contenido relacionado

La actualidad más candente

What's new in Rails 2?
What's new in Rails 2?What's new in Rails 2?
What's new in Rails 2?brynary
 
Practical PHP by example Jan Leth-Kjaer
Practical PHP by example   Jan Leth-KjaerPractical PHP by example   Jan Leth-Kjaer
Practical PHP by example Jan Leth-KjaerCOMMON Europe
 
Jquery presentation
Jquery presentationJquery presentation
Jquery presentationguest5d87aa6
 
Web Development Course: PHP lecture 2
Web Development Course: PHP lecture 2Web Development Course: PHP lecture 2
Web Development Course: PHP lecture 2Gheyath M. Othman
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Balázs Tatár
 
Evolution of API With Blogging
Evolution of API With BloggingEvolution of API With Blogging
Evolution of API With BloggingTakatsugu Shigeta
 
Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019Balázs Tatár
 
Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11Goro Fuji
 
2014 database - course 2 - php
2014 database - course 2 - php2014 database - course 2 - php
2014 database - course 2 - phpHung-yu Lin
 
Php Tutorial | Introduction Demo | Basics
 Php Tutorial | Introduction Demo | Basics Php Tutorial | Introduction Demo | Basics
Php Tutorial | Introduction Demo | BasicsShubham Kumar Singh
 
HTML Templates Using Clear Silver
HTML Templates Using Clear SilverHTML Templates Using Clear Silver
HTML Templates Using Clear SilverPaulWay
 
Introducation to php for beginners
Introducation to php for beginners Introducation to php for beginners
Introducation to php for beginners musrath mohammad
 
Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019Balázs Tatár
 
Getting started with MongoDB and PHP
Getting started with MongoDB and PHPGetting started with MongoDB and PHP
Getting started with MongoDB and PHPgates10gen
 
IPW HTML course
IPW HTML courseIPW HTML course
IPW HTML courseVlad Posea
 

La actualidad más candente (18)

Further Php
Further PhpFurther Php
Further Php
 
What's new in Rails 2?
What's new in Rails 2?What's new in Rails 2?
What's new in Rails 2?
 
Practical PHP by example Jan Leth-Kjaer
Practical PHP by example   Jan Leth-KjaerPractical PHP by example   Jan Leth-Kjaer
Practical PHP by example Jan Leth-Kjaer
 
Jquery presentation
Jquery presentationJquery presentation
Jquery presentation
 
Web Development Course: PHP lecture 2
Web Development Course: PHP lecture 2Web Development Course: PHP lecture 2
Web Development Course: PHP lecture 2
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
 
Ruby on discuz
Ruby on discuzRuby on discuz
Ruby on discuz
 
Evolution of API With Blogging
Evolution of API With BloggingEvolution of API With Blogging
Evolution of API With Blogging
 
Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019
 
Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11
 
Changing Template Engine
Changing Template EngineChanging Template Engine
Changing Template Engine
 
2014 database - course 2 - php
2014 database - course 2 - php2014 database - course 2 - php
2014 database - course 2 - php
 
Php Tutorial | Introduction Demo | Basics
 Php Tutorial | Introduction Demo | Basics Php Tutorial | Introduction Demo | Basics
Php Tutorial | Introduction Demo | Basics
 
HTML Templates Using Clear Silver
HTML Templates Using Clear SilverHTML Templates Using Clear Silver
HTML Templates Using Clear Silver
 
Introducation to php for beginners
Introducation to php for beginners Introducation to php for beginners
Introducation to php for beginners
 
Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019
 
Getting started with MongoDB and PHP
Getting started with MongoDB and PHPGetting started with MongoDB and PHP
Getting started with MongoDB and PHP
 
IPW HTML course
IPW HTML courseIPW HTML course
IPW HTML course
 

Destacado

Tdd in php a brief example
Tdd in php   a brief exampleTdd in php   a brief example
Tdd in php a brief exampleJeremy Kendall
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
Php 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodPhp 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodJeremy Kendall
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data ObjectsWez Furlong
 
TDC SP 2015 - PHP7: melhor e mais rápido
TDC SP 2015 - PHP7: melhor e mais rápidoTDC SP 2015 - PHP7: melhor e mais rápido
TDC SP 2015 - PHP7: melhor e mais rápidoBruno Ricardo Siqueira
 

Destacado (7)

Tdd in php a brief example
Tdd in php   a brief exampleTdd in php   a brief example
Tdd in php a brief example
 
Django a whirlwind tour
Django   a whirlwind tourDjango   a whirlwind tour
Django a whirlwind tour
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
Php 101: PDO
Php 101: PDOPhp 101: PDO
Php 101: PDO
 
Php 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the GoodPhp 102: Out with the Bad, In with the Good
Php 102: Out with the Bad, In with the Good
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data Objects
 
TDC SP 2015 - PHP7: melhor e mais rápido
TDC SP 2015 - PHP7: melhor e mais rápidoTDC SP 2015 - PHP7: melhor e mais rápido
TDC SP 2015 - PHP7: melhor e mais rápido
 

Similar a PHP 102: Out with the Bad, In with the Good

03 Php Array String Functions
03 Php Array String Functions03 Php Array String Functions
03 Php Array String FunctionsGeshan Manandhar
 
PHP Basics for Designers
PHP Basics for DesignersPHP Basics for Designers
PHP Basics for DesignersMatthew Turland
 
Php Calling Operators
Php Calling OperatorsPhp Calling Operators
Php Calling Operatorsmussawir20
 
Introduction To Lamp
Introduction To LampIntroduction To Lamp
Introduction To LampAmzad Hossain
 
Php Crash Course
Php Crash CoursePhp Crash Course
Php Crash Coursemussawir20
 
Php Training
Php TrainingPhp Training
Php Trainingadfa
 
Haml & Sass presentation
Haml & Sass presentationHaml & Sass presentation
Haml & Sass presentationbryanbibat
 
The Basics Of Page Creation
The Basics Of Page CreationThe Basics Of Page Creation
The Basics Of Page CreationWildan Maulana
 
Terms of endearment - the ElasticSearch Query DSL explained
Terms of endearment - the ElasticSearch Query DSL explainedTerms of endearment - the ElasticSearch Query DSL explained
Terms of endearment - the ElasticSearch Query DSL explainedclintongormley
 
Optimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile DevicesOptimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile DevicesSugree Phatanapherom
 
High-level Web Testing
High-level Web TestingHigh-level Web Testing
High-level Web Testingpetersergeant
 
Forum Presentation
Forum PresentationForum Presentation
Forum PresentationAngus Pratt
 

Similar a PHP 102: Out with the Bad, In with the Good (20)

03 Php Array String Functions
03 Php Array String Functions03 Php Array String Functions
03 Php Array String Functions
 
PHP Basics for Designers
PHP Basics for DesignersPHP Basics for Designers
PHP Basics for Designers
 
Php Calling Operators
Php Calling OperatorsPhp Calling Operators
Php Calling Operators
 
Introduction To Lamp
Introduction To LampIntroduction To Lamp
Introduction To Lamp
 
Web Scraping with PHP
Web Scraping with PHPWeb Scraping with PHP
Web Scraping with PHP
 
Php Crash Course
Php Crash CoursePhp Crash Course
Php Crash Course
 
Os Nixon
Os NixonOs Nixon
Os Nixon
 
Php
PhpPhp
Php
 
Php Sq Lite
Php Sq LitePhp Sq Lite
Php Sq Lite
 
Php Training
Php TrainingPhp Training
Php Training
 
Haml & Sass presentation
Haml & Sass presentationHaml & Sass presentation
Haml & Sass presentation
 
The Basics Of Page Creation
The Basics Of Page CreationThe Basics Of Page Creation
The Basics Of Page Creation
 
JQuery 101
JQuery 101JQuery 101
JQuery 101
 
JQuery Basics
JQuery BasicsJQuery Basics
JQuery Basics
 
Terms of endearment - the ElasticSearch Query DSL explained
Terms of endearment - the ElasticSearch Query DSL explainedTerms of endearment - the ElasticSearch Query DSL explained
Terms of endearment - the ElasticSearch Query DSL explained
 
Optimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile DevicesOptimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile Devices
 
Php My Sql
Php My SqlPhp My Sql
Php My Sql
 
High-level Web Testing
High-level Web TestingHigh-level Web Testing
High-level Web Testing
 
Forum Presentation
Forum PresentationForum Presentation
Forum Presentation
 
Ae internals
Ae internalsAe internals
Ae internals
 

Más de Jeremy Kendall

Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
5 Ways to Awesome-ize Your (PHP) Code
5 Ways to Awesome-ize Your (PHP) Code5 Ways to Awesome-ize Your (PHP) Code
5 Ways to Awesome-ize Your (PHP) CodeJeremy Kendall
 
Game Changing Dependency Management
Game Changing Dependency ManagementGame Changing Dependency Management
Game Changing Dependency ManagementJeremy Kendall
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkJeremy Kendall
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkJeremy Kendall
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkJeremy Kendall
 
TDD in PHP - Memphis PHP 2011-08-25
TDD in PHP - Memphis PHP 2011-08-25TDD in PHP - Memphis PHP 2011-08-25
TDD in PHP - Memphis PHP 2011-08-25Jeremy Kendall
 
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormZend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormJeremy Kendall
 
Zero to ZF in 10 Minutes
Zero to ZF in 10 MinutesZero to ZF in 10 Minutes
Zero to ZF in 10 MinutesJeremy Kendall
 
A Brief Introduction to Zend_Form
A Brief Introduction to Zend_FormA Brief Introduction to Zend_Form
A Brief Introduction to Zend_FormJeremy Kendall
 
Zero to Zend Framework in 10 minutes
Zero to Zend Framework in 10 minutesZero to Zend Framework in 10 minutes
Zero to Zend Framework in 10 minutesJeremy Kendall
 

Más de Jeremy Kendall (11)

Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
5 Ways to Awesome-ize Your (PHP) Code
5 Ways to Awesome-ize Your (PHP) Code5 Ways to Awesome-ize Your (PHP) Code
5 Ways to Awesome-ize Your (PHP) Code
 
Game Changing Dependency Management
Game Changing Dependency ManagementGame Changing Dependency Management
Game Changing Dependency Management
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
TDD in PHP - Memphis PHP 2011-08-25
TDD in PHP - Memphis PHP 2011-08-25TDD in PHP - Memphis PHP 2011-08-25
TDD in PHP - Memphis PHP 2011-08-25
 
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormZend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
 
Zero to ZF in 10 Minutes
Zero to ZF in 10 MinutesZero to ZF in 10 Minutes
Zero to ZF in 10 Minutes
 
A Brief Introduction to Zend_Form
A Brief Introduction to Zend_FormA Brief Introduction to Zend_Form
A Brief Introduction to Zend_Form
 
Zero to Zend Framework in 10 minutes
Zero to Zend Framework in 10 minutesZero to Zend Framework in 10 minutes
Zero to Zend Framework in 10 minutes
 

Último

Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.YounusS2
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxUdaiappa Ramachandran
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemAsko Soukka
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxMatsuo Lab
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfJamie (Taka) Wang
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarPrecisely
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxGDSC PJATK
 

Último (20)

Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptx
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystem
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
Introduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptxIntroduction to Matsuo Laboratory (ENG).pptx
Introduction to Matsuo Laboratory (ENG).pptx
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity Webinar
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptx
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 

PHP 102: Out with the Bad, In with the Good

  • 1. PHP 102 Out with the Bad, In with the Good Memphis PHP, February 23, 2012
  • 2.
  • 3.
  • 4. Why Did You Start Programming?
  • 5. I wanted to solve problems, but . . .
  • 6. . . . I frequently caused as many problems as I solved.
  • 7.
  • 10. Make a cool improvement
  • 12.
  • 13.
  • 16.
  • 17.
  • 21. index.php – db connection <?php $db = realpath ( dirname ( __FILE__ ) . '/data/db/bookshelf.db' ); $dsn = &quot;sqlite: $db &quot; ; $options = array ( PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION , PDO :: ATTR_DEFAULT_FETCH_MODE => PDO :: FETCH_ASSOC ); try { $dbh = new PDO ( $dsn , null , null , $options ); } catch ( PDOException $e ) { echo &quot;Error!: &quot; . $e -> getMessage() . &quot;<br /> &quot; ; die (); } $books = $dbh -> query( &quot; SELECT * FROM bookshelf ORDER BY title&quot; ) -> fetchAll();
  • 22. index.php – db connection <?php $db = realpath ( dirname ( __FILE__ ) . '/data/db/bookshelf.db' ); $dsn = &quot;sqlite: $db &quot; ; $options = array ( PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION , PDO :: ATTR_DEFAULT_FETCH_MODE => PDO :: FETCH_ASSOC ); try { $dbh = new PDO ($dsn, null , null , $options); } catch ( PDOException $e) { echo &quot;Error!: &quot; . $e -> getMessage() . &quot;<br />&quot;; die (); } $books = $dbh -> query(&quot; SELECT * FROM bookshelf ORDER BY title&quot;) -> fetchAll() ;
  • 23. index.php – db connection <?php $db = realpath ( dirname ( __FILE__ ) . '/data/db/bookshelf.db'); $dsn = &quot;sqlite:$db&quot;; $options = array ( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ); try { $dbh = new PDO ( $dsn , null , null , $options ); } catch ( PDOException $e ) { echo &quot;Error!: &quot; . $e -> getMessage() . &quot;<br /> &quot; ; die (); } $books = $dbh -> query(&quot; SELECT * FROM bookshelf ORDER BY title&quot;) -> fetchAll();
  • 24. index.php – db connection <?php $db = realpath ( dirname ( __FILE__ ) . '/data/db/bookshelf.db'); $dsn = &quot;sqlite:$db&quot;; $options = array ( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ); try { $dbh = new PDO ($dsn, null , null , $options); } catch ( PDOException $e) { echo &quot;Error!: &quot; . $e -> getMessage() . &quot;<br />&quot;; die (); } $books = $dbh -> query( &quot; SELECT * FROM bookshelf ORDER BY title&quot; ) -> fetchAll();
  • 26. index.php – books table <?php if ( count ( $books ) > 0 ): ?> < table > < tr > < th > Title </ th >< th > Author </ th > </ tr > <?php foreach ( $books as $book ): ?> < tr > < td > < a href= &quot;book-form.php?id=<?php echo $book ['id']; ?>&quot; > <?php echo $book [ 'title' ]; ?> </ a > </ td > < td > <?php echo $book [ 'author' ]; ?> </ td > </ tr > <?php endforeach ; ?> </ table > <?php else : ?> < p > We have no books! </ p > <?php endif ; ?>
  • 27. index.php – books table <?php if ( count ( $books ) > 0 ): ?> < table > < tr > < th > Title </ th >< th > Author </ th > </ tr > <?php foreach ( $books as $book ): ?> < tr > < td > < a href= &quot;book-form.php?id=<?php echo $book ['id']; ?>&quot; > <?php echo $book [ 'title' ]; ?> </ a > </ td > < td > <?php echo $book [ 'author' ]; ?> </ td > </ tr > <?php endforeach ; ?> </ table > <?php else : ?> < p >We have no books!</ p > <?php endif ; ?>
  • 28. index.php – books table <?php if ( count ($books) > 0): ?> < table > < tr > < th >Title</ th >< th >Author</ th > </ tr > <?php foreach ( $books as $book ): ?> < tr > < td > < a href= &quot;book-form.php?id=<?php echo $book ['id']; ?>&quot; > <?php echo $book [ 'title' ]; ?> </ a > </ td > < td > <?php echo $book [ 'author' ]; ?> </ td > </ tr > <?php endforeach ; ?> </ table > <?php else : ?> < p >We have no books!</ p > <?php endif ; ?>
  • 29. index.php – books table <?php if ( count ($books) > 0): ?> < table > < tr > < th >Title</ th >< th >Author</ th > </ tr > <?php foreach ($books as $book): ?> < tr > < td > < a href=&quot;book-form.php?id=<?php echo $book['id']; ?>&quot;> <?php echo $book['title']; ?> </ a > </ td > < td > <?php echo $book['author']; ?> </ td > </ tr > <?php endforeach ; ?> </ table > <?php else : ?> < p > We have no books! </ p > <?php endif ; ?>
  • 30.  
  • 32. book-form.php <?php $id = empty ( $_GET [ 'id' ]) ? null : $_GET [ 'id' ]; if ( $id ) { // Database connection code $book = $dbh -> query( &quot; SELECT title, author FROM bookshelf WHERE id = $id &quot; ) -> fetch(); $title = $book [ 'title' ]; $author = $book [ 'author' ]; }
  • 33. book-form.php <?php $id = empty ( $_GET [ 'id' ]) ? null : $_GET [ 'id' ]; if ($id) { // Database connection code $book = $dbh -> query(&quot; SELECT title, author FROM bookshelf WHERE id = $id&quot;) -> fetch(); $title = $book['title']; $author = $book['author']; }
  • 34. book-form.php <?php $id = empty ($_GET['id']) ? null : $_GET['id']; if ( $id ) { // Database connection code $book = $dbh -> query( &quot; SELECT title, author FROM bookshelf WHERE id = $id &quot; ) -> fetch(); $title = $book [ 'title' ]; $author = $book [ 'author' ]; }
  • 35. book-form.php < form method= &quot;post&quot; action= &quot;process-book.php&quot; > < input type= &quot;hidden&quot; id= &quot;id&quot; name= &quot;id&quot; value= &quot;<?php echo $id ; ?>&quot; /> < dl > < dt > < label for= &quot;title&quot; > Title </ label > </ dt > < dd > < input type= &quot;text&quot; id= &quot;title&quot; name= &quot;title&quot; value= &quot;<?php echo $title ; ?>&quot; /> </ dd > < dt > < label for= &quot;author&quot; > Author </ label > </ dt > < dd > < input type= &quot;text&quot; id= &quot;author&quot; name= &quot;author&quot; value= &quot;<?php echo $author ; ?>&quot; /> </ dd > < dt > &nbsp; </ dt > < dd > < input type= &quot;submit&quot; value= &quot;Submit&quot; /> </ dd > </ dl > </ form >
  • 36. book-form.php < form method= &quot;post&quot; action= &quot;process-book.php&quot; > < input type=&quot;hidden&quot; id=&quot;id&quot; name=&quot;id&quot; value= &quot;<?php echo $id ; ?>&quot; /> < dl > < dt > < label for=&quot;title&quot;>Title</ label > </ dt > < dd > < input type=&quot;text&quot; id=&quot;title&quot; name=&quot;title&quot; value= &quot;<?php echo $title ; ?>&quot; /> </ dd > < dt > < label for=&quot;author&quot;>Author</ label > </ dt > < dd > < input type=&quot;text&quot; id=&quot;author&quot; name=&quot;author&quot; value= &quot;<?php echo $author ; ?>&quot; /> </ dd > < dt > &nbsp; </ dt > < dd > < input type=&quot;submit&quot; value=&quot;Submit&quot; /> </ dd > </ dl > </ form >
  • 37. process-book.php <?php if ( strtolower ( $_SERVER [ 'REQUEST_METHOD' ]) == 'get' ) { header ( &quot;Location: /&quot; ); } // Database connection code if ( empty ( $_POST [ 'id' ])) { $sql = &quot; INSERT INTO bookshelf (title, author) &quot; . &quot;VALUES ('{ $_POST ['title']}', '{ $_POST ['author']}')&quot; ; $dbh -> exec( $sql ); } else { $sql = &quot; UPDATE bookshelf SET title = '{ $_POST ['title']}', &quot; . &quot;author = '{ $_POST ['author']}' WHERE id = { $_POST ['id']}&quot; ; $dbh -> exec( $sql ); } header ( &quot;Location: /&quot; );
  • 38. process-book.php <?php if ( strtolower ( $_SERVER [ 'REQUEST_METHOD' ]) == 'get' ) { header ( &quot;Location: /&quot; ); } // Database connection code if ( empty ($_POST['id'])) { $sql = &quot; INSERT INTO bookshelf (title, author) &quot; . &quot;VALUES ('{$_POST['title']}', '{$_POST['author']}')&quot;; $dbh -> exec($sql); } else { $sql = &quot; UPDATE bookshelf SET title = '{$_POST['title']}', &quot; . &quot;author = '{$_POST['author']}' WHERE id = {$_POST['id']}&quot;; $dbh -> exec($sql); } header (&quot;Location: /&quot;);
  • 39. process-book.php <?php if ( strtolower ($_SERVER['REQUEST_METHOD']) == 'get') { header (&quot;Location: /&quot;); } // Database connection code if ( empty ($_POST['id'])) { $sql = &quot; INSERT INTO bookshelf (title, author) &quot; . &quot;VALUES ('{$_POST['title']}', '{$_POST['author']}')&quot;; $dbh -> exec($sql); } else { $sql = &quot; UPDATE bookshelf SET title = '{$_POST['title']}', &quot; . &quot;author = '{$_POST['author']}' WHERE id = {$_POST['id']}&quot;; $dbh -> exec($sql); } header (&quot;Location: /&quot;);
  • 40. process-book.php <?php if ( strtolower ($_SERVER['REQUEST_METHOD']) == 'get') { header (&quot;Location: /&quot;); } // Database connection code if ( empty ( $_POST [ 'id' ])) { $sql = &quot; INSERT INTO bookshelf (title, author) &quot; . &quot;VALUES ('{ $_POST ['title']}', '{ $_POST ['author']}')&quot; ; $dbh -> exec( $sql ); } else { $sql = &quot; UPDATE bookshelf SET title = '{$_POST['title']}', &quot; . &quot;author = '{$_POST['author']}' WHERE id = {$_POST['id']}&quot;; $dbh -> exec($sql); } header (&quot;Location: /&quot;);
  • 41. process-book.php <?php if ( strtolower ($_SERVER['REQUEST_METHOD']) == 'get') { header (&quot;Location: /&quot;); } // Database connection code if ( empty ($_POST['id'])) { $sql = &quot; INSERT INTO bookshelf (title, author) &quot; . &quot;VALUES ('{$_POST['title']}', '{$_POST['author']}')&quot;; $dbh -> exec($sql); } else { $sql = &quot; UPDATE bookshelf SET title = '{ $_POST ['title']}', &quot; . &quot;author = '{ $_POST ['author']}' WHERE id = { $_POST ['id']}&quot; ; $dbh -> exec( $sql ); } header (&quot;Location: /&quot;);
  • 42. process-book.php <?php if ( strtolower ($_SERVER['REQUEST_METHOD']) == 'get') { header (&quot;Location: /&quot;); } // Database connection code if ( empty ($_POST['id'])) { $sql = &quot; INSERT INTO bookshelf (title, author) &quot; . &quot;VALUES ('{$_POST['title']}', '{$_POST['author']}')&quot;; $dbh -> exec($sql); } else { $sql = &quot; UPDATE bookshelf SET title = '{$_POST['title']}', &quot; . &quot;author = '{$_POST['author']}' WHERE id = {$_POST['id']}&quot;; $dbh -> exec($sql); } header ( &quot;Location: /&quot; );
  • 43.
  • 47.
  • 49. The next developer will want to kill you
  • 52.
  • 53. base.php <?php date_default_timezone_set ('America/Chicago'); error_reporting ( - 1); ini_set ('display_errors', 1); ini_set ('display_startup_errors', 1); $db = realpath ( dirname ( __FILE__ ) . '/../data/db/bookshelf.db' ); $dsn = &quot;sqlite: $db &quot; ; $options = array ( PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION , PDO :: ATTR_DEFAULT_FETCH_MODE => PDO :: FETCH_ASSOC ); try { $dbh = new PDO ( $dsn , null , null , $options ); } catch ( PDOException $e ) { throw $e ; echo &quot;Error!: &quot; . $e -> getMessage() . &quot;<br /> &quot; ; die (); }
  • 54. base.php <?php date_default_timezone_set ( 'America/Chicago' ); error_reporting ( - 1); ini_set ('display_errors', 1); ini_set ('display_startup_errors', 1); $db = realpath ( dirname ( __FILE__ ) . '/../data/db/bookshelf.db'); $dsn = &quot;sqlite:$db&quot;; $options = array ( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ); try { $dbh = new PDO ($dsn, null , null , $options); } catch ( PDOException $e) { throw $e; echo &quot;Error!: &quot; . $e -> getMessage() . &quot;<br />&quot;; die (); }
  • 55. base.php <?php date_default_timezone_set ('America/Chicago'); error_reporting ( - 1 ); ini_set ( 'display_errors' , 1 ); ini_set ( 'display_startup_errors' , 1 ); $db = realpath ( dirname ( __FILE__ ) . '/../data/db/bookshelf.db'); $dsn = &quot;sqlite:$db&quot;; $options = array ( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION , PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ); try { $dbh = new PDO ($dsn, null , null , $options); } catch ( PDOException $e) { throw $e; echo &quot;Error!: &quot; . $e -> getMessage() . &quot;<br />&quot;; die (); }
  • 56.
  • 58.  
  • 59. We echo $title and $author < form method=&quot;post&quot; action=&quot;process-book.php&quot;> < input type=&quot;hidden&quot; id=&quot;id&quot; name=&quot;id&quot; value=&quot;<?php echo $id; ?>&quot; /> < dl > < dt > < label for=&quot;title&quot;>Title</ label > </ dt > < dd > < input type=&quot;text&quot; id=&quot;title&quot; name=&quot;title&quot; value= &quot;<?php echo $title ; ?>&quot; /> </ dd > < dt > < label for=&quot;author&quot;>Author</ label > </ dt > < dd > < input type=&quot;text&quot; id=&quot;author&quot; name=&quot;author&quot; value= &quot;<?php echo $author ; ?>&quot; /> </ dd > < dt > &nbsp; </ dt > < dd > < input type=&quot;submit&quot; value=&quot;Submit&quot; /> </ dd > </ dl > </ form >
  • 60. Without defining $title and $author require_once dirname ( __FILE__ ) . '/library/base.php' ; $id = empty ( $_GET [ 'id' ]) ? null : $_GET [ 'id' ]; if ( $id ) { $book = $dbh -> query( . . . ) -> fetch(); $title = $book [ 'title' ]; $author = $book [ 'author' ]; }
  • 61. Super easy to fix require_once dirname ( __FILE__ ) . '/library/base.php'; $id = empty ($_GET['id']) ? null : $_GET['id']; $title = null ; $author = null ; if ($id) { $book = $dbh -> query( . . . ) -> fetch(); $title = $book['title']; $author = $book['author']; }
  • 62.
  • 63.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70. Help protect against SQL injection
  • 71. Easier to read and maintain
  • 72. book-form.php: Before $book = $dbh -> query( &quot; SELECT title, author FROM bookshelf WHERE id = $id &quot; ) -> fetch();
  • 73. book-form.php: After $statement = $dbh -> prepare( ' SELECT title, author FROM bookshelf WHERE id = :id' ); $statement -> bindParam( ':id' , $id ); $statement -> execute(); $book = $statement -> fetch();
  • 74. book-form.php: After $statement = $dbh -> prepare (' SELECT title, author FROM bookshelf WHERE id = :id'); $statement -> bindParam(':id', $id); $statement -> execute(); $book = $statement -> fetch();
  • 75. book-form.php: After $statement = $dbh -> prepare( ' SELECT title, author FROM bookshelf WHERE id = :id' ); $statement -> bindParam(':id', $id); $statement -> execute(); $book = $statement -> fetch();
  • 76. book-form.php: After $statement = $dbh -> prepare(' SELECT title, author FROM bookshelf WHERE id = :id'); $statement -> bindParam( ':id' , $id ); $statement -> execute(); $book = $statement -> fetch();
  • 77. book-form.php: After $statement = $dbh -> prepare(' SELECT title, author FROM bookshelf WHERE id = :id'); $statement -> bindParam(':id', $id); $statement -> execute(); $book = $statement -> fetch();
  • 78. process-book.php: Before if ( empty ( $_POST [ 'id' ])) { $sql = &quot; INSERT INTO bookshelf (title, author) &quot; . &quot;VALUES ('{ $_POST ['title']}', '{ $_POST ['author']}')&quot; ; $dbh -> exec( $sql ); } else { $sql = &quot; UPDATE bookshelf SET title = '{ $_POST ['title']}', &quot; . &quot;author = '{ $_POST ['author']}' WHERE id = { $_POST ['id']}&quot; ; $dbh -> exec( $sql ); }
  • 79. process-book.php: After if ( $id ) { $statement = $dbh -> prepare( &quot; UPDATE bookshelf SET title = :title, author = :author WHERE id = :id&quot; ); $statement -> bindParam( ':title' , $title ); $statement -> bindParam( ':author' , $author ); $statement -> bindParam( ':id' , $id ); $statement -> execute(); } else { $statement = $dbh -> prepare( &quot; INSERT INTO bookshelf (title, author) VALUES (:title, :author)&quot; ); $statement -> bindParam( ':title' , $title ); $statement -> bindParam( ':author' , $author ); $statement -> execute(); }
  • 80. process-book.php: After if ( $id ) { $statement = $dbh -> prepare( &quot; UPDATE bookshelf SET title = :title, author = :author WHERE id = :id&quot; ); $statement -> bindParam(':title', $title); $statement -> bindParam(':author', $author); $statement -> bindParam(':id', $id); $statement -> execute(); } else { $statement = $dbh -> prepare( &quot; INSERT INTO bookshelf (title, author) VALUES (:title, :author)&quot; ); $statement -> bindParam(':title', $title); $statement -> bindParam(':author', $author); $statement -> execute(); }
  • 81. process-book.php: After if ($id) { $statement = $dbh -> prepare(&quot; UPDATE bookshelf SET title = :title, author = :author WHERE id = :id&quot;); $statement -> bindParam( ':title' , $title ); $statement -> bindParam( ':author' , $author ); $statement -> bindParam( ':id' , $id ); $statement -> execute(); } else { $statement = $dbh -> prepare(&quot; INSERT INTO bookshelf (title, author) VALUES (:title, :author)&quot;); $statement -> bindParam( ':title' , $title ); $statement -> bindParam( ':author' , $author ); $statement -> execute(); }
  • 82. process-book.php: After if ($id) { $statement = $dbh -> prepare(&quot; UPDATE bookshelf SET title = :title, author = :author WHERE id = :id&quot;); $statement -> bindParam(':title', $title); $statement -> bindParam(':author', $author); $statement -> bindParam(':id', $id); $statement -> execute(); } else { $statement = $dbh -> prepare(&quot; INSERT INTO bookshelf (title, author) VALUES (:title, :author)&quot;); $statement -> bindParam(':title', $title); $statement -> bindParam(':author', $author); $statement -> execute(); }
  • 83.
  • 85. Unused in this app (besides PDO)
  • 86.
  • 87. Take advantage of namespaces
  • 88.
  • 90.
  • 95. (The class name should mirror its location in the file system)
  • 96. BookshelfService.php namespace Bookshelfervice; class BookshelfService { private $_dbh ; public function __construct (PDO $dbh ) { } public function find ( $id ) { } public function findAll () { } public function save ( array $options ) { } }
  • 97. BookshelfService.php private $_dbh ; public function __construct (PDO $dbh ) { $this -> _dbh = $dbh ; }
  • 98. BookshelfService.php public function find ( $id ) { $sql = ' SELECT * FROM bookshelf WHERE id = :id' ; $statement = $this -> _dbh -> prepare( $sql ); $statement -> bindParam( ':id' , $id ); $statement -> execute(); return $statement -> fetch(); } public function findAll () { $sql = ' SELECT * FROM bookshelf ORDER BY title' ; return $this -> _dbh -> query( $sql ) -> fetchAll(); }
  • 99. BookshelfService.php public function save ( array $options ) { if ( $options [ 'id' ]) { $statement = $this -> _dbh -> prepare( &quot; UPDATE bookshelf SET title = :title, author = :author WHERE id = :id&quot; ); $statement -> execute( $options ); } else { unset ( $options [ 'id' ]); $statement = $this -> _dbh -> prepare( &quot; INSERT INTO bookshelf (title, author) VALUES (:title, :author)&quot; ); $statement -> execute( $options ); } }
  • 100.
  • 101. base.php set_include_path ( implode ( PATH_SEPARATOR , array ( get_include_path (), dirname ( __FILE__ ) ) ) );
  • 102. base.php function autoload ( $className ) { $className = ltrim ( $className , ' ' ); $fileName = '' ; $namespace = '' ; if ( $lastNsPos = strripos ( $className , ' ' )) { $namespace = substr ( $className , 0 , $lastNsPos ); $className = substr ( $className , $lastNsPos + 1 ); $fileName = str_replace ( ' ' , DIRECTORY_SEPARATOR , $namespace ) . DIRECTORY_SEPARATOR ; } $fileName .= str_replace ( '_' , DIRECTORY_SEPARATOR , $className ) . '.php' ; require $fileName ; } spl_autoload_register ( 'autoload' );
  • 103. base.php // database connection code $bookshelf = new BookshelferviceBookshelfService ( $dbh );
  • 104. And now for some before and after shots . . .
  • 105. index.php: Before <?php require_once dirname ( __FILE__ ) . '/library/base.php' ; $books = $dbh -> query( &quot; SELECT * FROM bookshelf ORDER BY title&quot; ) -> fetchAll(); ?>
  • 106. index.php: After <?php require_once dirname ( __FILE__ ) . '/library/base.php' ; $books = $bookshelf -> findAll(); ?>
  • 107. book-form.php: Before if ( $id ) { $statement = $dbh -> prepare( ' SELECT title, author FROM bookshelf WHERE id = :id' ); $statement -> bindParam( ':id' , $id ); $statement -> execute(); $book = $statement -> fetch(); $title = $book['title']; $author = $book['author']; }
  • 108. book-form.php: After if ( $id ) { $book = $bookshelf -> find( $id ); $title = $book['title']; $author = $book['author']; }
  • 109. process-book.php: Before if ( $id ) { $statement = $dbh -> prepare( &quot; UPDATE bookshelf SET title = :title, author = :author WHERE id = :id&quot; ); $statement -> bindParam( ':title' , $title ); $statement -> bindParam( ':author' , $author ); $statement -> bindParam( ':id' , $id ); $statement -> execute(); } else { $statement = $dbh -> prepare( &quot; INSERT INTO bookshelf (title, author) VALUES (:title, :author)&quot; ); $statement -> bindParam( ':title' , $title ); $statement -> bindParam( ':author' , $author ); $statement -> execute(); }
  • 110. process-book.php: After $book = array ( 'id' => $id , 'title' => $title , 'author' => $author ); $bookshelf -> save( $book );
  • 111.
  • 112. Made and corrected some typical mistakes
  • 113.
  • 116.
  • 117.
  • 118. PHP Manual: http://www.php.net/manual/en/index.php
  • 119. CSI: PHP http://csiphp.com
  • 120. PHP 101 Suggestions: http://csiphp.com/blog/2011/07/19/stop-doing-it-wrong-and-learn-to-code-good-too/
  • 121. PHP 101: PHP for the Absolute Beginner: http://devzone.zend.com/6/php-101-php-for-the-absolute-beginner/
  • 124.