SlideShare a Scribd company logo
1 of 78
[object Object],[object Object]
Who is this guy? ,[object Object],[object Object]
Following Along ,[object Object]
What is PHP? ,[object Object]
Designed for the web
Cross-platform
Free (as in beer)
Getting started ,[object Object]
Included in OS X
Mac: MAMP, MacPorts, Homebrew . . .
Windows: WampServer, xampp
Google, follow instructions, and . . .
. . . you can be coding in about 5 minutes
Why Did You  (or why do you want to) Start Programming?
I Wanted to Solve Problems ,[object Object]
We'll solve a problem together
Create a typical first web application
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
book-form.php
Database Schema CREATE   TABLE   bookshelf  (   id  INTEGER   PRIMARY KEY ,   title,   author );
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 – 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 <?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 ,[object Object]
Maintenance nightmare
The next developer will thank you
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 (); }
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' ; ,[object Object]
Duplication removed, but . . . ,[object Object]
Oops
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
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

More Related Content

What's hot

Evolution of API With Blogging
Evolution of API With BloggingEvolution of API With Blogging
Evolution of API With BloggingTakatsugu Shigeta
 
Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11Goro Fuji
 
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
 
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
 
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
 
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
 
Jquery presentation
Jquery presentationJquery presentation
Jquery presentationguest5d87aa6
 
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
 
Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019Balázs Tatár
 
Inside a Digital Collection: Historic Clothing in Omeka
Inside a Digital Collection: Historic Clothing in OmekaInside a Digital Collection: Historic Clothing in Omeka
Inside a Digital Collection: Historic Clothing in OmekaArden Kirkland
 

What's hot (18)

Ruby on discuz
Ruby on discuzRuby on discuz
Ruby on discuz
 
Further Php
Further PhpFurther Php
Further Php
 
Evolution of API With Blogging
Evolution of API With BloggingEvolution of API With Blogging
Evolution of API With Blogging
 
Changing Template Engine
Changing Template EngineChanging Template Engine
Changing Template Engine
 
Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11Xslate sv perl-2013-7-11
Xslate sv perl-2013-7-11
 
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
 
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
 
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
 
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
 
Jquery presentation
Jquery presentationJquery presentation
Jquery presentation
 
Introducation to php for beginners
Introducation to php for beginners Introducation to php for beginners
Introducation to php for beginners
 
Php with my sql
Php with my sqlPhp with my sql
Php with my sql
 
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
 
Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019
 
Inside a Digital Collection: Historic Clothing in Omeka
Inside a Digital Collection: Historic Clothing in OmekaInside a Digital Collection: Historic Clothing in Omeka
Inside a Digital Collection: Historic Clothing in Omeka
 
Oo Perl
Oo PerlOo Perl
Oo Perl
 

Viewers also liked

Illinois Health Care Spring It Technology Conference
Illinois Health Care Spring It Technology ConferenceIllinois Health Care Spring It Technology Conference
Illinois Health Care Spring It Technology Conferencejfsheridan
 
A Brief Introduction to Zend_Form
A Brief Introduction to Zend_FormA Brief Introduction to Zend_Form
A Brief Introduction to Zend_FormJeremy 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
 
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
 
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
 
Tdd in php a brief example
Tdd in php   a brief exampleTdd in php   a brief example
Tdd in php a brief exampleJeremy Kendall
 
Didactica concepto, objeto y finalidades
Didactica   concepto, objeto y finalidadesDidactica   concepto, objeto y finalidades
Didactica concepto, objeto y finalidadesAlejandro De Greef
 
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
 

Viewers also liked (8)

Illinois Health Care Spring It Technology Conference
Illinois Health Care Spring It Technology ConferenceIllinois Health Care Spring It Technology Conference
Illinois Health Care Spring It Technology Conference
 
A Brief Introduction to Zend_Form
A Brief Introduction to Zend_FormA Brief Introduction to Zend_Form
A Brief Introduction to Zend_Form
 
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
 
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
 
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
 
Tdd in php a brief example
Tdd in php   a brief exampleTdd in php   a brief example
Tdd in php a brief example
 
Didactica concepto, objeto y finalidades
Didactica   concepto, objeto y finalidadesDidactica   concepto, objeto y finalidades
Didactica concepto, objeto y finalidades
 
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
 

Similar to Intro to #memtech PHP 2011-12-05

PHP Basics for Designers
PHP Basics for DesignersPHP Basics for Designers
PHP Basics for DesignersMatthew Turland
 
03 Php Array String Functions
03 Php Array String Functions03 Php Array String Functions
03 Php Array String FunctionsGeshan Manandhar
 
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
 
The Basics Of Page Creation
The Basics Of Page CreationThe Basics Of Page Creation
The Basics Of Page CreationWildan Maulana
 
Optimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile DevicesOptimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile DevicesSugree Phatanapherom
 
PHP Presentation
PHP PresentationPHP Presentation
PHP PresentationAnkush Jain
 
Haml & Sass presentation
Haml & Sass presentationHaml & Sass presentation
Haml & Sass presentationbryanbibat
 
Zendcon 2007 Features
Zendcon 2007 FeaturesZendcon 2007 Features
Zendcon 2007 Featuresfivespeed5
 
Forum Presentation
Forum PresentationForum Presentation
Forum PresentationAngus Pratt
 

Similar to Intro to #memtech PHP 2011-12-05 (20)

PHP Basics for Designers
PHP Basics for DesignersPHP Basics for Designers
PHP Basics for Designers
 
03 Php Array String Functions
03 Php Array String Functions03 Php Array String Functions
03 Php Array String Functions
 
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
 
Php Training
Php TrainingPhp Training
Php Training
 
The Basics Of Page Creation
The Basics Of Page CreationThe Basics Of Page Creation
The Basics Of Page Creation
 
Php
PhpPhp
Php
 
Php Sq Lite
Php Sq LitePhp Sq Lite
Php Sq Lite
 
Os Nixon
Os NixonOs Nixon
Os Nixon
 
Optimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile DevicesOptimizing Drupal for Mobile Devices
Optimizing Drupal for Mobile Devices
 
PHP Presentation
PHP PresentationPHP Presentation
PHP Presentation
 
Haml & Sass presentation
Haml & Sass presentationHaml & Sass presentation
Haml & Sass presentation
 
Php My Sql
Php My SqlPhp My Sql
Php My Sql
 
Ae internals
Ae internalsAe internals
Ae internals
 
Zendcon 2007 Features
Zendcon 2007 FeaturesZendcon 2007 Features
Zendcon 2007 Features
 
JQuery Basics
JQuery BasicsJQuery Basics
JQuery Basics
 
Forum Presentation
Forum PresentationForum Presentation
Forum Presentation
 
SlideShare Instant
SlideShare InstantSlideShare Instant
SlideShare Instant
 

More from 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
 
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
 

More from Jeremy Kendall (9)

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
 
Php 101: PDO
Php 101: PDOPhp 101: PDO
Php 101: PDO
 
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
 

Recently uploaded

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 

Recently uploaded (20)

SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 

Intro to #memtech PHP 2011-12-05

  • 1.
  • 2.
  • 3.
  • 4.
  • 7. Free (as in beer)
  • 8.
  • 10. Mac: MAMP, MacPorts, Homebrew . . .
  • 13. . . . you can be coding in about 5 minutes
  • 14. Why Did You (or why do you want to) Start Programming?
  • 15.
  • 16. We'll solve a problem together
  • 17. Create a typical first web application
  • 20. Make a cool improvement
  • 22.
  • 23.
  • 26.
  • 27.
  • 33. Database Schema CREATE TABLE bookshelf ( id INTEGER PRIMARY KEY , title, author );
  • 34. 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();
  • 35. 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() ;
  • 36. 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();
  • 37. 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();
  • 38. 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 ; ?>
  • 39. 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 ; ?>
  • 40. 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 ; ?>
  • 41. 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 ; ?>
  • 42. 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' ]; }
  • 43. 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']; }
  • 44. 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' ]; }
  • 45. 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 >
  • 46. 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 >
  • 47. 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; );
  • 48. 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;);
  • 49. 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;);
  • 50. 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;);
  • 51. 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;);
  • 52. 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; );
  • 53.
  • 57.
  • 59. The next developer will thank you
  • 60.
  • 61. 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 (); }
  • 62. 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 (); }
  • 63. 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 (); }
  • 64. 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 (); }
  • 65.
  • 66.
  • 67. Oops
  • 68. 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 >
  • 69. 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' ]; }
  • 70. 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']; }
  • 71.
  • 72.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78. Help protect against SQL injection
  • 79. Easier to read and maintain
  • 80. book-form.php $statement = $dbh -> prepare( ' SELECT title, author FROM bookshelf WHERE id = :id' ); $statement -> bindParam( ':id' , $id ); $statement -> execute(); $book = $statement -> fetch();
  • 81. book-form.php $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'];
  • 82. book-form.php $statement = $dbh -> prepare( ' SELECT title, author FROM bookshelf WHERE id = :id' ); $statement -> bindParam(':id', $id); $statement -> execute(); $book = $statement -> fetch();
  • 83. book-form.php $statement = $dbh -> prepare(' SELECT title, author FROM bookshelf WHERE id = :id'); $statement -> bindParam( ':id' , $id ); $statement -> execute(); $book = $statement -> fetch();
  • 84. book-form.php $statement = $dbh -> prepare(' SELECT title, author FROM bookshelf WHERE id = :id'); $statement -> bindParam(':id', $id); $statement -> execute(); $book = $statement -> fetch();
  • 85. process-book.php 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(); }
  • 86. process-book.php 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(); }
  • 87. process-book.php 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(); }
  • 88. process-book.php 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(); }
  • 89.
  • 91. Unused in this app (besides PDO)
  • 92. Let's create a service layer
  • 93. Introduces some OOP principles
  • 94.
  • 96.
  • 101. (The class name should mirror its location in the file system)
  • 102. 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 ) { } }
  • 103. BookshelfService.php private $_dbh ; public function __construct (PDO $dbh ) { $this -> _dbh = $dbh ; }
  • 104. 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(); }
  • 105. 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 ); } }
  • 106.
  • 107. base.php set_include_path ( implode ( PATH_SEPARATOR , array ( get_include_path (), dirname ( __FILE__ ) ) ) );
  • 108. 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' );
  • 109. base.php // database connection code $bookshelf = new BookshelferviceBookshelfService ( $dbh );
  • 110. And now for some before and after shots . . .
  • 111. index.php: Before <?php require_once dirname ( __FILE__ ) . '/library/base.php' ; $books = $dbh -> query( &quot; SELECT * FROM bookshelf ORDER BY title&quot; ) -> fetchAll(); ?>
  • 112. index.php: After <?php require_once dirname ( __FILE__ ) . '/library/base.php' ; $books = $bookshelf -> findAll(); ?>
  • 113. 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']; }
  • 114. book-form.php: After if ( $id ) { $book = $bookshelf -> find( $id ); $title = $book['title']; $author = $book['author']; }
  • 115. 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(); }
  • 116. process-book.php: After $book = array ( 'id' => $id , 'title' => $title , 'author' => $author ); $bookshelf -> save( $book );
  • 117.
  • 118. Made and corrected some typical mistakes
  • 119.
  • 122.
  • 123.
  • 124. Presentation source code: https://github.com/jeremykendall/bookshelf
  • 125. PHP Manual: http://www.php.net/manual/en/index.php
  • 126. CSI: PHP http://csiphp.org
  • 127. PHP 101 Suggestions: http://csiphp.com/blog/2011/07/19/stop-doing-it-wrong-and-learn-to-code-good-too/
  • 128. PHP 101: PHP for the Absolute Beginner: http://devzone.zend.com/6/php-101-php-for-the-absolute-beginner/
  • 130.