Você está na página 1de 9

30.10.

2013

How to Connect to a Database with PDO | Nettuts+

PHP Database Access: Are You Doing It Correctly?


Jeffrey Way on May 31st 2012 with 138 Comments

Tutorial Details
Topic - Database Access in PHP Difficulty - Moderate View post on Tuts+ BetaTuts+ Beta is an optimized, mobile-friendly and easy-to-read version of the Tuts+ network. We've covered PHP's PDO API a couple of times here on Nettuts+, but, generally, those articles focused more on the theory, and less on the application. This article will fix that! To put it plainly, if you're still using PHP's old m y s q lAPI to connect to your databases, read on!

What?
It's possible that, at this point, the only thought in your mind is, "What the heck is PDO?" Well, it's one of PHP's three available APIs for connecting to a MySQL database. "Three," you say? Yes; many folks don't know it, but there are three different APIs for connecting:
m y s q l m y s q l i

MySQL Improved p d o PHP Data Objects The traditional m y s q lAPI certainly gets the job done, and has become so popular largely due to the fact that it makes the process of retrieving some records from a database as easy as possible. For example:
net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/ 1/9

30.10.2013

How to Connect to a Database with PDO | Nettuts+

1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8

/ * *A n t i P a t t e r n * /

#C o n n e c t m y s q l _ c o n n e c t ( ' l o c a l h o s t ' ,' u s e r n a m e ' ,' p a s s w o r d ' )o rd i e ( ' C o u l dn o tc o n n e #C h o o s ead a t a b a s e m y s q l _ s e l e c t _ d b ( ' s o m e D a t a b a s e ' )o rd i e ( ' C o u l dn o ts e l e c td a t a b a s e ' ) ; #P e r f o r md a t a b a s eq u e r y $ q u e r y=" S E L E C T*f r o ms o m e T a b l e " ; $ r e s u l t=m y s q l _ q u e r y ( $ q u e r y )o rd i e ( ' Q u e r yf a i l e d :'.m y s q l _ e r r o r ( ) ) ; #F i l t e rt h r o u g hr o w sa n de c h od e s i r e di n f o r m a t i o n w h i l e( $ r o w=m y s q l _ f e t c h _ o b j e c t ( $ r e s u l t ) ){ e c h o$ r o w > n a m e ; }

Yes, the code above is fairly simple, but it does come with its significant share of downsides. Deprecated: Though it hasn't been officially deprecated due to widespread use in terms of best practice and education, it might as well be. Escaping: The process of escaping user input is left to the developer many of which don't understand or know how to sanitize the data. Flexibility: The API isn't flexible; the code above is tailor-made for working with a MySQL database. What if you switch? PDO, or PHP Data Objects, provides a more powerful API that doesn't care about the driver you use; it's database agnostic. Further, it offers the ability to use prepared statements, virtually eliminating any worry of SQL injection.

How?
When I was first learning about the PDO API, I must admit that it was slightly intimidating. This wasn't because the API was overly complicated (it's not) it's just that the old m y q s lAPI was so dang easy to use! Don't worry, though; follow these simple steps, and you'll be up and running in no time.

Connect
So you already know the legacy way of connecting to a MySQL database: 1 2

#C o n n e c t m y s q l _ c o n n e c t ( ' l o c a l h o s t ' ,' u s e r n a m e ' ,' p a s s w o r d ' )o rd i e ( ' C o u l dn o tc o n n e c


2/9

net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/

30.10.2013

How to Connect to a Database with PDO | Nettuts+

With PDO, we create a new instance of the class, and specify the driver, database name, username, and password like so: 1

$ c o n n=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = m y D a t a b a s e ' ,$ u s e r n a m e ,$ p a s s w

Don't let that long string confuse you; it's really very simple: we specify the name of the driver (mysql, in this case), followed by the required details (connection string) for connecting to it. What's nice about this approach is that, if we instead wish to use a sqlite database, we simply update the DSN, or "Data Source Name," accordingly; we're not dependent upon MySQL in the way that we are when use functions, like m y s q l _ c o n n e c t .

Errors
But, what if there's an error, and we can't connect to the database? Well, let's wrap everything within a t r y / c a t c hblock: 1 2 3 4 5 6 t r y{ $ c o n n=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = m y D a t a b a s e ' ,$ u s e r n a m e $ c o n n > s e t A t t r i b u t e ( P D O : : A T T R _ E R R M O D E ,P D O : : E R R M O D E _ E X C E P T I O N ) ; }c a t c h ( P D O E x c e p t i o n$ e ){ e c h o' E R R O R :'.$ e > g e t M e s s a g e ( ) ; }

That's better! Please note that, by default, the default error mode for PDO is P D O : : E R R M O D E _ S I L E N T . With this setting left unchanged, you'll need to manually fetch errors, after performing a query. 1 2 e c h o$ c o n n > e r r o r C o d e ( ) ; e c h o$ c o n n > e r r o r I n f o ( ) ;

Instead, a better choice, during development, is to update this setting to P D O : : E R R M O D E _ E X C E P T I O N , which will fire exceptions as they occur. This way, any uncaught exceptions will halt the script. For reference, the available options are:
P D O : : E R R M O D E _ S I L E N T P D O : : E R R M O D E _ W A R N I N G P D O : : E R R M O D E _ E X C E P T I O N

Fetch
At this point, we've created a connection to the database; let's fetch some information from it. There's two core ways to accomplish this task: q u e r yand e x e c u t e . We'll review both.
net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/ 3/9

30.10.2013

How to Connect to a Database with PDO | Nettuts+

Query
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 / * *T h eQ u e r yM e t h o d *A n t i P a t t e r n * / $ n a m e=' J o e ' ;#u s e r s u p p l i e dd a t a t r y{ $ c o n n=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = m y D a t a b a s e ' ,$ u s e r n a m e $ c o n n > s e t A t t r i b u t e ( P D O : : A T T R _ E R R M O D E ,P D O : : E R R M O D E _ E X C E P T I O N ) ; $ d a t a=$ c o n n > q u e r y ( ' S E L E C T*F R O Mm y T a b l eW H E R En a m e='.$ c o n n f o r e a c h ( $ d a t aa s$ r o w ){ p r i n t _ r ( $ r o w ) ; } }c a t c h ( P D O E x c e p t i o n$ e ){ e c h o' E R R O R :'.$ e > g e t M e s s a g e ( ) ; }

Though this works, notice that we're still manually escaping the user's data with the P D O : : q u o t emethod. Think of this method as, more or less, the PDO equivalent to use m y s q l _ r e a l _ e s c a p e _ s t r i n g ; it will both escape and quote the string that you pass to it. In situations, when you're binding user-supplied data to a SQL query, it's strongly advised that you instead use prepared statements. That said, if your SQL queries are not dependent upon form data, the q u e r ymethod is a helpful choice, and makes the process of looping through the results as easy as a f o r e a c hstatement.

Prepared Statements
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 / * *T h eP r e p a r e dS t a t e m e n t sM e t h o d *B e s tP r a c t i c e * / $ i d=5 ; t r y{ $ c o n n=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = m y D a t a b a s e ' ,$ u s e r n a m e $ c o n n > s e t A t t r i b u t e ( P D O : : A T T R _ E R R M O D E ,P D O : : E R R M O D E _ E X C E P T I O N ) ; $ s t m t=$ c o n n > p r e p a r e ( ' S E L E C T*F R O Mm y T a b l eW H E R Ei d=: i d ' ) ; $ s t m t > e x e c u t e ( a r r a y ( ' i d '= >$ i d ) ) ; w h i l e ( $ r o w=$ s t m t > f e t c h ( ) ){ p r i n t _ r ( $ r o w ) ; }
4/9

net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/

30.10.2013

How to Connect to a Database with PDO | Nettuts+

1 7 1 8 1 9

}c a t c h ( P D O E x c e p t i o n$ e ){ e c h o' E R R O R :'.$ e > g e t M e s s a g e ( ) ; }

In this example, we're using the p r e p a r emethod to, literally, prepare the query, before the user's data has been attached. With this technique, SQL injection is virtually impossible, because the data doesn't ever get inserted into the SQL query, itself. Notice that, instead, we use named parameters (: i d ) to specify placeholders. Alternatively, you could use ?parameters, however, it makes for a less-readable experience. Stick with named parameters. Next, we execute the query, while passing an array, which contains the data that should be bound to those placeholders. 1 $ s t m t > e x e c u t e ( a r r a y ( ' i d '= >$ i d ) ) ;

An alternate, but perfectly acceptable, approach would be to use the b i n d P a r a mmethod, like so: 1 2 $ s t m t > b i n d P a r a m ( ' : i d ' ,$ i d ,P D O : : P A R A M _ I N T ) ; $ s t m t > e x e c u t e ( ) ;

Specifying the Ouput


After calling the e x e c u t emethod, there are a variety of different ways to receive the data: an array (the default), an object, etc. In the example above, the default response is used: P D O : : F E T C H _ A S S O C ; this can easily be overridden, though, if necessary: 1 2 3 w h i l e ( $ r o w=$ s t m t > f e t c h ( P D O : : F E T C H _ O B J ) ){ p r i n t _ r ( $ r o w ) ; }

Now, we've specified that we want to interact with the result set in a more object-oriented fashion. Available choices include, but not limited to: PDO::FETCH_ASSOC: Returns an array. PDO::FETCH_BOTH: Returns an array, indexed by both column-name, and 0-indexed. PDO::FETCH_BOUND: Returns TRUE and assigns the values of the columns in your result set to the PHP variables to which they were bound. PDO::FETCH_CLASS: Returns a new instance of the specified class. PDO::FETCH_OBJ: Returns an anonymous object, with property names that correspond to the columns. One problem with the code above is that we aren't providing any feedback, if no results are returned. Let's fix that: 1 2 $ s t m t > e x e c u t e ( a r r a y ( ' i d '= >$ i d ) ) ;
5/9

net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/

30.10.2013

How to Connect to a Database with PDO | Nettuts+

3 4 5 6 7 8 9 1 0 1 1 1 2 1 3

#G e ta r r a yc o n t a i n i n ga l lo ft h er e s u l tr o w s $ r e s u l t=$ s t m t > f e t c h A l l ( ) ; #I fo n eo rm o r er o w sw e r er e t u r n e d . . . i f(c o u n t ( $ r e s u l t )){ f o r e a c h ( $ r e s u l ta s$ r o w ){ p r i n t _ r ( $ r o w ) ; } }e l s e{ e c h o" N or o w sr e t u r n e d . " ; }

At this point, our full code should look like so: 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 $ i d=5 ; t r y{ $ c o n n=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = s o m e D a t a b a s e ' ,$ u s e r n a m e $ s t m t=$ c o n n > p r e p a r e ( ' S E L E C T*F R O Mm y T a b l eW H E R Ei d=: i d ' ) ; $ s t m t > e x e c u t e ( a r r a y ( ' i d '= >$ i d ) ) ; $ r e s u l t=$ s t m t > f e t c h A l l ( ) ; i f(c o u n t ( $ r e s u l t )){ f o r e a c h ( $ r e s u l ta s$ r o w ){ p r i n t _ r ( $ r o w ) ; } }e l s e{ e c h o" N or o w sr e t u r n e d . " ; } }c a t c h ( P D O E x c e p t i o n$ e ){ e c h o' E R R O R :'.$ e > g e t M e s s a g e ( ) ; }

Multiple Executions
The PDO extension becomes particularly powerful when executing the same SQL query multiple times, but with different parameters. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 t r y{ $ c o n n=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = s o m e D a t a b a s e ' ,$ u s e r n a m e $ c o n n > s e t A t t r i b u t e ( P D O : : A T T R _ E R R M O D E ,P D O : : E R R M O D E _ E X C E P T I O N ) ; #P r e p a r et h eq u e r yO N C E $ s t m t=$ c o n n > p r e p a r e ( ' I N S E R TI N T Os o m e T a b l eV A L U E S ( : n a m e ) ' ) ; $ s t m t > b i n d P a r a m ( ' : n a m e ' ,$ n a m e ) ; #F i r s ti n s e r t i o n $ n a m e=' K e i t h ' ; $ s t m t > e x e c u t e ( ) ;
6/9

net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/

30.10.2013

How to Connect to a Database with PDO | Nettuts+

1 3 1 4 1 5 1 6 1 7 1 8

#S e c o n di n s e r t i o n $ n a m e=' S t e v e n ' ; $ s t m t > e x e c u t e ( ) ; }c a t c h ( P D O E x c e p t i o n$ e ){ e c h o$ e > g e t M e s s a g e ( ) ; }

Once the query has been prepared, it can be executed multiple times, with different parameters. The code above will insert two rows into the database: one with a name of Kevin, and the other, Steven.

CRUD
Now that you have the basic process in place, lets quickly review the various CRUD tasks. As youll find, the required code for each is virtually identical.

Create (Insert)
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 t r y{ $ p d o=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = s o m e D a t a b a s e ' ,$ u s e r n a m e $ p d o > s e t A t t r i b u t e ( P D O : : A T T R _ E R R M O D E ,P D O : : E R R M O D E _ E X C E P T I O N ) ; $ s t m t=$ p d o > p r e p a r e ( ' I N S E R TI N T Os o m e T a b l eV A L U E S ( : n a m e ) ' ) ; $ s t m t > e x e c u t e ( a r r a y ( ' : n a m e '= >' J u s t i nB i e b e r ' ) ) ; #A f f e c t e dR o w s ? e c h o$ s t m t > r o w C o u n t ( ) ;/ /1 }c a t c h ( P D O E x c e p t i o n$ e ){ e c h o' E r r o r :'.$ e > g e t M e s s a g e ( ) ;

Update
1 2 3 4 5 6 7 8 9 1 0 1 1 $ i d=5 ; $ n a m e=" J o et h eP l u m b e r " ; t r y{ $ p d o=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = s o m e D a t a b a s e ' ,$ u s e r n a m e $ p d o > s e t A t t r i b u t e ( P D O : : A T T R _ E R R M O D E ,P D O : : E R R M O D E _ E X C E P T I O N ) ;

$ s t m t=$ p d o > p r e p a r e ( ' U P D A T Es o m e T a b l eS E Tn a m e=: n a m eW H E R Ei d=: i d ' $ s t m t > e x e c u t e ( a r r a y ( ' : i d ' = >$ i d , ' : n a m e '= >$ n a m e
7/9

net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/

30.10.2013

How to Connect to a Database with PDO | Nettuts+

1 2 1 3 1 4 1 5 1 6 1 7

) ) ; e c h o$ s t m t > r o w C o u n t ( ) ;/ /1 }c a t c h ( P D O E x c e p t i o n$ e ){ e c h o' E r r o r :'.$ e > g e t M e s s a g e ( ) ; }

Delete
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 $ i d=5 ;/ /F r o maf o r mo rs o m e t h i n gs i m i l a r t r y{ $ p d o=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = s o m e D a t a b a s e ' ,$ u s e r n a m e $ p d o > s e t A t t r i b u t e ( P D O : : A T T R _ E R R M O D E ,P D O : : E R R M O D E _ E X C E P T I O N ) ;

$ s t m t=$ p d o > p r e p a r e ( ' D E L E T EF R O Ms o m e T a b l eW H E R Ei d=: i d ' ) ; $ s t m t > b i n d P a r a m ( ' : i d ' ,$ i d ) ;/ /t h i st i m e ,w e ' l lu s et h eb i n d P a r a mm e t h $ s t m t > e x e c u t e ( ) ; e c h o$ s t m t > r o w C o u n t ( ) ;/ /1 }c a t c h ( P D O E x c e p t i o n$ e ){ e c h o' E r r o r :'.$ e > g e t M e s s a g e ( ) ; }

Object Mapping
One of the neatest aspects of PDO (mysqli, as well) is that it gives us the ability to map the query results to a class instance, or object. Heres an example: 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 c l a s sU s e r{ p u b l i c$ f i r s t _ n a m e ; p u b l i c$ l a s t _ n a m e ; p u b l i cf u n c t i o nf u l l _ n a m e ( ) { r e t u r n$ t h i s > f i r s t _ n a m e.''.$ t h i s > l a s t _ n a m e ; }

t r y{ $ p d o=n e wP D O ( ' m y s q l : h o s t = l o c a l h o s t ; d b n a m e = s o m e D a t a b a s e ' ,$ u s e r n a m e $ p d o > s e t A t t r i b u t e ( P D O : : A T T R _ E R R M O D E ,P D O : : E R R M O D E _ E X C E P T I O N ) ; $ r e s u l t=$ p d o > q u e r y ( ' S E L E C T*F R O Ms o m e T a b l e ' ) ; #M a pr e s u l t st oo b j e c t $ r e s u l t > s e t F e t c h M o d e ( P D O : : F E T C H _ C L A S S ,' U s e r ' ) ;
8/9

net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/

30.10.2013

How to Connect to a Database with PDO | Nettuts+

1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6

w h i l e ( $ u s e r=$ r e s u l t > f e t c h ( ) ){ #C a l lo u rc u s t o mf u l l _ n a m em e t h o d e c h o$ u s e r > f u l l _ n a m e ( ) ; } }c a t c h ( P D O E x c e p t i o n$ e ){ e c h o' E r r o r :'.$ e > g e t M e s s a g e ( ) ; }

Closing Thoughts
Bottom line: if youre still using that old m y s q lAPI for connecting to your databases, stop. Though it hasnt yet been deprecated, in terms of education and documentation, it might as well be. Your code will be significantly more secure and streamlined if you adopt the PDO extension.
Like 562 people like this. Be the first of your friends.

Tags: Databases

By Jeffrey Way
As the head of web development courses at Tuts+ Premium and creator of Laracasts.com, I love making the process of building for the web as easy as possible. I'm incredibly passionate about modern software development, and am the author of Laravel Testing Decoded! If you want be friends, say hi on Twitter.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more

net.tutsplus.com/tutorials/php/php-database-access-are-you-doing-it-correctly/

9/9

Você também pode gostar