I Can't Reach A DB Using PDO - php

I'm following a tutorial that is teaching PDO but I'm stuck at a very early point.
Referring to the code below I have diagnosed the problem down to the DB selected.
When I run print_r($query); there is no output and initallally I thought the problem was that the script wasn't connecting to the MySql server at all but then I learned if I change anything in host, user or pass I get an error message, but no matter what I change related to the database nothing happens and no error messages are displayed.
<?php
error_reporting(E_ALL);
$config['db'] = array(
'host' => 'xxxx',
'user' => 'xxxx',
'pass' => 'xxxx',
'database' => 'xxxx'
);
$db = new PDO('mysql:host=' . $config['db']['host'] . ';database=' . $config['db']['database'],$config['db']['user'], $config['db']['pass']);
$query = $db->query("SELECT `subscribers`.`first_name` FROM `subscribers`");
print_r($query);
echo 'Anything';
?>
If anyone could show me what Im doing wrong I'd be most appreciative and I thank you in advance.
BTW, I am SURE that SELECT subscribers.first_name FROM subscribers is correct as this works when I insert it into the mysql tab within php MyAdmin

I believe the DSN parameter for database name is called dbname, not database.
Try this:
$db = new PDO('mysql:host=' . $config['db']['host'] . ';dbname=' . $config['db']['database'],$config['db']['user'], $config['db']['pass']);

After creating a connection with database you need to create a statement, set query, bind values(optional), execute the query and fetch the result. In your case:
$db = new PDO('mysql:host=' . $config['db']['host'] . ';database=' . $config['db'] ['database'],$config['db']['user'], $config['db']['pass']);
$query = $db->prepare("SELECT `subscribers`.`first_name` FROM `subscribers`");
$query->execute();
$result = $query->fetchAll();
var_dump($result);

Related

MySQL vs Firebird: accessing query columns in PHP with PDO

From what I understood, using PDO should be the same result regardless of what DB I am using. I tested this in the following code, which I have connected to two separate DB's.
$sth = $pdo->query('SELECT * FROM posts');
while($result = $sth->fetch(PDO::FETCH_BOTH)){
echo $result[1] . '<br>';
};
MySQL DB:
$dsn = 'mysql:host=' . $server . ';dbname=' . $dbname;
$pdo = new PDO($dsn, $username, $password);
Firebird DB:
$dsn = "firebird:dbname=" . $server . ":" . $dbname;
$pdo = new PDO($dsn, $username, $password);
The MySQL connection worked fine, while the Firebird connection worked only with numbered Arrays - FETCH_NUM, and FETCH_BOTH when using index positions. Is this how its supposed to be or am I doing something wrong with my Firebird connection? I will need to work with the Firebird DB in the future, so this really frustrates me. Thank you for all comments.
In Firebird, by default, mainly from historical reasons, unless you use double quotes on object names (field names, tables, etc...), they are uppercase-d and stored internally in uppercase.
Accordingly, the column names you receive in result set are in uppercase, so you should address them in upper-case like $row['FIELD_NAME'].
Alternatively, in PHP, PDO driver have a special flag used on connection, PDO::ATTR_CASE => PDO::CASE_LOWER/NATURAL/UPPER that adjust the needed case internally for you.
For example:
$source = $d['kind'].':'.'dbname='.$d['host'].':'.$d['base'].';charset='.$d['charset'];
$options = $d['options'] + [
\PDO::ATTR_CASE => \PDO::CASE_LOWER,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
];
$connection = new \PDO($source, $d['user'], $d['password'], $options);
Firebird is not alone doing this. Oracle also stores by default metadata in uppercase. Some DBMSes have options, others in lower-case by default.

Different solution to `Cannot execute queries while other unbuffered queries are active`

I've just migrated from MySQL to newer MariaDB and all my websites are now showing:
Cannot execute queries while other unbuffered queries are active.
Consider using PDOStatement::fetchAll(). Alternatively, if your code
is only ever going to run against mysql, you may enable query
buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
I googled this error and tried doing what people suggested.
So I changed my code to use PDO's closeCursor().
I tried using PDO::MYSQL_ATTR_USE_BUFFERED_QUERY and nothing works.
And here's how my constructor looked:
$pdo = new PDO('mysql:host=' . $host . ';dbname=' . $db . ';port=' . $port, $user, $pass,
array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8;SET SESSION time_zone="system"',
PDO::MYSQL_ATTR_LOCAL_INFILE => true
));
I changed it to
$pdo = new PDO('mysql:host=' . $host . ';dbname=' . $db . ';port=' . $port, $user, $pass,
array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8, SESSION time_zone="system"',
PDO::MYSQL_ATTR_LOCAL_INFILE => true
));
and it does work now.
I am posting my solution here because all other places have "wrong" ones.
So the difference is instead of having
'SET NAMES utf8;SET SESSION time_zone="system"'
in PDO::MYSQL_ATTR_INIT_COMMAND I have:
'SET NAMES utf8, SESSION time_zone="system"'
and everything's fine now.

PHP PDO INSERT query running twice

I've got this code with PHP PDO and I've got an INSERT query that runs twice. This code should insert the value 'Hello World' into the database. However, my code inserts the value twice into the database.
How do I fix this? I've stumbled upon other people with the same problem, but they have problems with a loop or they've used the explode function that messed something up. I don't have any of that, just one connection block and an insert query, and yet it does this weird thing.
The code:
// DB connect configuration
$user = 'user';
$pass = 'password';
// Database connection
$dsn = "mysql:host=localhost;dbname=pdotest;charset=utf8";
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$conn = new PDO($dsn, $user, $pass, $opt);
// Data to insert
$data = 'Test and test and test';
// Insert data into database
$sql = "INSERT INTO tabletwo (rowTwo) VALUES (?)";
$q = $conn->prepare($sql);
$q->execute(array($data));
It's happening because of some Javascript code for page transitions. The code can be found here: http://www.fasw.ws/faswwp/non-jquery-page-transitions-lightweight/. I have no idea how to fix this though.

PHP command line persistent connections

I have a PHP script which works perfectly via Apache called through a browser, but the same code called on command line seems to drop the database connection after every call.
So for instance in an included file I have:
$pdo = new PDO('mysql:host=' . HOST . ';dbname=' . DB, USER, PASS, array(PDO::ATTR_PERSISTENT => true));
Then in my script I have:
$stmt = $pdo->prepare('SELECT intGroupID FROM tblquestiongroups WHERE dtDeleted IS NOT NULL ORDER BY RAND()');
$stmt->execute();
$something = $stmt->fetch(PDO::FETCH_ASSOC);
Which works fine, however directly afterwards I have:
$stmt = $pdo->prepare('SELECT intSurveyID FROM tblquestiongroups WHERE tblquestiongroups.intGroupID = :intQuestionId');
$stmt->bindValue(':intQuestionId', $intQuestionId);
$stmt->execute();
Which doesn't and returns:
Call to member function bindValue() on a non-object
Now if I add a new connection, i.e. copy and paste the one in the include file above the second call it all works fine again, i.e.:
$pdo = new PDO('mysql:host=' . HOST . ';dbname=' . DB, USER, PASS, array(PDO::ATTR_PERSISTENT => true));
$stmt = $pdo->prepare('SELECT intSurveyID FROM tblquestiongroups WHERE tblquestiongroups.intGroupID = :intQuestionId');
$stmt->bindValue(':intQuestionId', $intQuestionId);
$stmt->execute();
My first question is why won't PHP keep the connection open for the period of the script?
So onto my second question. As a test I went through and added the connection before all of the calls to database via PDO. Within this script I actually connect to two different servers and as such I have another connection defined which looks like this:
$pdoLocal = new PDO('mysql:host=' . HOST_LOCAL . ';dbname=' . DB_LOCAL, USER_LOCAL, PASS_LOCAL, array(PDO::ATTR_PERSISTENT => true));
So of course to try and get the thing working I have added this line above any calls to the local database. However with this code:
$pdoLocal = new PDO('mysql:host=' . HOST_LOCAL . ';dbname=' . DB_LOCAL, USER_LOCAL, PASS_LOCAL, array(PDO::ATTR_PERSISTENT => true));
$pdoLocal->beginTransaction();
$stmtInsert = $pdoLocal->prepare('INSERT INTO tblresponses_string (strResponses, intSurveyID) VALUES (:strResponses, :intSurveyID)');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$stmtInsert->bindValue(':strResponses', $row['strResponses']);
$stmtInsert->bindValue(':intSurveyID', $surveyID);
$stmtInsert->execute();
}
$pdoLocal->commit();
I get the same error on the first bind.
I guess this is the same problem in that the first statement to get executed is beginTransaction and the PDO connection closes afterwards.
As mentioned this all works fine through Apache.
All help gratefully received.
Your speculations are wrong.
If PHP were indeed dropping a connection, you'd had an error not on bindValue call but on the line where the very PDO connection is used, so, the error would be
Call to member function prepare() on a non-object
So, the problem is not with connection but with query. Set PDO in error mode:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
then see the error message and then either fix it or ask another question regarding this particular error.

PHP PDO - can connect but query not working

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
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
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.
PDO won't throw an error unless you configure it to:
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );

Categories