2

I want to wean myself from the teat of the old mysql extension and am just doing a test PDO connection and simple query on a table in a database. I seem to be able to connect, ('connection successful' echoes out) but that's where the good times end. I have spent way too much time now just trying to get started with PDO.

<?php
$host = 'localhost';
$port = '3306'; 
$username = 'user';
$password = 'blabla';
$database = 'workslist';

try {
    $db = new PDO("mysql:host=$host; port = $port; dbname = $database", $username, $password);
    echo 'connection successful<br />';

    $query = 'SELECT * FROM main';
    $statement = $db->prepare($query);
    $statement->execute();
    $results = $statement->fetchAll();
    $statement->closeCursor();      

    foreach($results as $r){
            echo $r['work'] . '<br />';
    }

} catch (PDOException $e) {
    echo 'Error!: ' . $e->getMessage() . '<br />';
    die();
} 
?>

Is there anything wrong with the above?

The database name is 'workslist', the table name is 'main', and 'work' is one of the columns in that table. The PHP version I'm using is 5.3.4, and am using wamp on win7. I ran phpinfo() and under the PDO heading, the PDO drivers mysql, sqlite are enabled. To be sure the database and table actually exist I've tried it with MySQL and can return rows with the old mysql_fetch_array() method. I've checked the php.ini file to make sure the "extension=php_pdo..." lines are all uncommented.

cheers

outis
  • 75,655
  • 22
  • 151
  • 221
berzerk
  • 65
  • 1
  • 3
  • 8
  • Note there are some things in the sample that are fine while learning, but shouldn't appear in production code. Don't use [`SELECT *`](http://stackoverflow.com/questions/321299/what-is-the-reason-not-to-use-select); select only the columns you need. Data access and display code should be kept in [separate](http://en.wikipedia.org/wiki/Separation_of_concerns) modules. – outis Dec 03 '11 at 05:37
  • thanks outis - I only used `SELECT *` in t his question to make the query as simple as possible. – berzerk Dec 03 '11 at 06:06
  • 1
    [`
    `](http://brainstormsandraves.com/articles/semantics/structure/#br) isn't [semantic](http://webstyleguide.com/wsg3/5-site-structure/2-semantic-markup.html). For production code, make sure you use something more appropriate, such as a paragraph or [list](http://www.w3.org/TR/html401/struct/lists.html) element. Don't use [`or die`](http://www.phpfreaks.com/blog/or-die-must-die) when outputting HTML. You'll get invalid HTML.
    – outis Dec 03 '11 at 09:38
  • Make sure you don't output DB error messages to non-admin users in production code; doing so [discloses too much information](http://msdn.microsoft.com/en-us/library/ms995351.aspx#securityerrormessages_topic2). `PDOStatement::fetchAll` is resource intensive; instead, iterate over the PDOStatement object, which implements the [`Traversable`](http://php.net/Traversable), with a `foreach` loop. "Statement" better describes the SQL "sentence"; "query" better describes what you execute to get results. – outis Dec 03 '11 at 09:42

3 Answers3

5

This should work.

Please double-check that you actually have a table named "main" in that database.

Note that this error will not be discovered by PDO until you execute() the query, and if there is a problem with your query the default behavior is to return an empty result, not throw an exception.

To make PDO noisier, add the PDO::ERRMODE_EXCEPTION option when constructing PDO:

$db = new PDO("mysql:host=$host;port=$port;dbname=$database", $username, $password, 
              array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION)
);

Now check if you see the following:

Error!: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'workslist.main' doesn't exist
Francis Avila
  • 31,233
  • 6
  • 58
  • 96
  • Thanks Francis - I got about 100 of these errors: 'Notice: Undefined variable: r in C:\wamp\www\PDOtest.php on line 25'. – berzerk Dec 03 '11 at 05:24
  • I'm looking at my phpmyadmin page of that database, and the table 'main' is definitely there, with a column named 'work' in that table. Thanks - it's good to be sure – berzerk Dec 03 '11 at 05:30
  • That is strange. What does a `var_dump($results)` reveal? – Francis Avila Dec 03 '11 at 05:37
  • AH HA! I think @outis has the answer! I didn't catch this because I automatically removed the spaces from the DSN when I was setting it to my own DB values to test. – Francis Avila Dec 03 '11 at 05:39
  • I took all the spaces out of the DSN (still no good). I'll remember that though - thanks – berzerk Dec 03 '11 at 05:47
2

The particular problem is that spaces aren't allowed in the DSN string. With the spaces, the "dbname" directive isn't processed, so there's no default database. Besides removing the spaces, explicitly specifying the database in the statement can help prevent this sort of problem:

SELECT `work` FROM `workslist`.`main`

That way, should there not be a default database for some reason, the query will still succeed.

outis
  • 75,655
  • 22
  • 151
  • 221
  • Now I'm confused - I just tried this?? $query = $db->prepare("SELECT 'work' FROM 'workslist'.'main'"); $query->execute(); – berzerk Dec 03 '11 at 05:44
  • @berzerk: single quotes denote strings; backticks denote identifiers. Database, table, and column names are identifiers and thus you should use backticks, not single quotes. – outis Dec 03 '11 at 05:46
  • so I tried this (not sure?) $query = $db->prepare("SELECT `work` FROM `workslist`.`main`"); 'Notice: Undefined variable: r in C:\wamp\www\PDOtest.php...' (this comment didn't include my new backticks - btw it didn't work either) – berzerk Dec 03 '11 at 05:58
  • @berzerk: SO's Q&A format isn't suited for discussion. The only incorrect aspect of the posted sample are the spaces in the DSN. If you're having another issue, search SO for an existing question about the same issue (the error you're getting is a good starting point), then post a new question only if you can't find an existing one. – outis Dec 03 '11 at 09:31
  • Thanks for your replies anyway - spaces are out of the DSN and still not working...I'll try later on a different server. cheers – berzerk Dec 03 '11 at 10:26
1

PDO won't throw an error unless you configure it to:

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
Robert Parham
  • 704
  • 3
  • 10