Solved

Warning: PDOStatement::fetch() expects parameter 2 to be long, string

Posted on 2013-12-06
22
1,776 Views
Last Modified: 2016-06-07
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
final example of fetch is generating this warning and no output
Warning: PDOStatement::fetch() expects parameter 2 to be long, string given in C:\wamp\www\oop-beg\pdo9.php on line 30

<?php
class secret_person{
  public $name;
  public $addr;
  public $city;
  public $other_data;
  
  function __construct($other=''){
    $this->addr=preg_replace('/[a-z]/','x',$this->addr);
    $this->other_data=$other;
  }
}

# connect to the database
try{
  $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);  
  $DBH->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
  #using the shortcut->query() method here since there is no variable
  #values in the select statement.
  $STH=$DBH->query('SELECT name,addr,city from test');
  #setting the fetch mode
  //$STH->setFetchMode(PDO::FETCH_CLASS | 'secret_person',array('stuff'));
  echo '<br>';
  $i=0;
  while($rowObj=$STH->fetch(PDO::FETCH_CLASS,'secret_person',array($i))){
    //echo $obj->name.'<br>';
    echo $obj->addr.'<br>';
    //echo $obj->city.'<br>';
  }
  
}
catch(PDOException $e){
  echo '<br>no results';
  echo '<br>$e:'.$e;
  echo '<br>$e->getMessage():'.$e->getMessage();
  file_put_contents('PDOErrors.txt',$e->getMessage(),FILE_APPEND);
}
$DBH=null;

Open in new window

0
Comment
Question by:rgb192
  • 7
  • 5
  • 5
  • +2
22 Comments
 
LVL 30

Expert Comment

by:Marco Gasi
ID: 39700381
Hi rgb192. See here: http://www.php.net/manual/en/pdostatement.fetch.php
The second parameter must be an integer value whgich indicates the cursor orientation. The parameter list you used here is valid for PDOStatement::setFetchMode (http://www.php.net/manual/en/pdostatement.setfetchmode.php)

So try to use

while($rowObj=$STH->fetch(PDO::FETCH_CLASS)){

letting default values to see if the result is what you expect it to be.
0
 
LVL 30

Expert Comment

by:Marco Gasi
ID: 39700410
Oh, here you can find all predefined constants for PDO:

http://www.php.net/manual/en/pdo.constants.php
0
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39700555
If you want to fetch your data into an object, then you set the FETCH_MODE and then call fetch(). You have commented out the FETCH_MODE line and tried to incorporate it into the fetch() call. You need something like this:

$STH->setFetchMode(PDO::FETCH_CLASS, 'secret_person');  
while($obj = $STH->fetch()) { 
   ...
}

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39700941
IIRC that was a good article but it had an error in the code sample.

Some things that I found consistently useful when working with PDO:
// SET PDO TO TELL US ABOUT WARNINGS OR TO THROW EXCEPTIONS
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

Open in new window

Run a query and get a PDO Statement Object:
try
{
    $pdos = $pdo->query($sql);
}
catch(PDOException $exc)
{
    var_dump($exc);
    trigger_error($exc->getMessage(), E_USER_ERROR);
}
// SHOW THE RESULTS OF THE QUERY
var_dump($pdos);

// DETERMINE HOW MANY ROWS OF RESULTS WE GOT
$num = $pdos->rowCount();

// ITERATE OVER THE RESULTS SET TO SHOW WHAT WE FOUND
echo "USING PDOStatement::FetchAll(PDO::FETCH_OBJ): ";
echo "<br/>" . PHP_EOL;
while ($row = $pdos->fetchAll(PDO::FETCH_OBJ))
{
    // ROW BY ROW PROCESSING IS DONE HERE
    foreach ($row as $key => $obj)
    {
        echo "$key: ";
        print_r($obj);
        echo PHP_EOL;
    }
}

Open in new window

0
 

Author Comment

by:rgb192
ID: 39701428
Marqus and Chris suggested earlier lessons in the tutorial where I could successfully run the code.



Was I correct in making changes to Ray's code to make code run?

# connect to the database
try
{
  $pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); 
  // SET PDO TO TELL US ABOUT WARNINGS OR TO THROW EXCEPTIONS
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql='SELECT name,addr,city from test';
    $pdos = $pdo->query($sql);
}
catch(PDOException $exc)
{
    var_dump($exc);
    trigger_error($exc->getMessage(), E_USER_ERROR);
}
// SHOW THE RESULTS OF THE QUERY
var_dump($pdos);

// DETERMINE HOW MANY ROWS OF RESULTS WE GOT
$num = $pdos->rowCount();

// ITERATE OVER THE RESULTS SET TO SHOW WHAT WE FOUND
echo "USING PDOStatement::FetchAll(PDO::FETCH_OBJ): ";
echo "<br/>" . PHP_EOL;
while ($row = $pdos->fetchAll(PDO::FETCH_OBJ))
{
    // ROW BY ROW PROCESSING IS DONE HERE
    foreach ($row as $key => $obj)
    {
        echo "$key: ";
        print_r($obj);
        echo PHP_EOL;
    }
}

Open in new window

0
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39701445
You're not fetching your data into your own object, which is what I thought you wanted - you're just fetching the data into a blank object.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39701497
Was I correct in making changes to Ray's code to make code run?
I would have isolated the try/catch blocks, but aside from that, I don't see anything grossly wrong with what you've got there.  But I don't have your data set to test it.  What do you get when you run it?
0
 
LVL 30

Expert Comment

by:Marco Gasi
ID: 39701556
I'm sorry, I recognize in that tutorial there is something I don't understand. the author suggests to use this code

while($rowObj=$STH->fetch(PDO::FETCH_CLASS,'secret_person',array($i))){

Open in new window


if one needs "to pass different data to the constructor for each object". rgb192 follows the tutorial strictly and he gets the error which is the reason of this thread.

I'm not able to explain why no one has never pointed at this if that code is wrong as it seems looking at Php.net manual.

@rgb192: only a side note: in your loop you should anyway increase $i value, otherwise the while loop doesn't make sense.
Hope Chris or Ray can clarify the problem: if the reason is that code is wrong, I apologize foe not having followed the tutorial as strictly as rgb192 does and for not having seen that error :(
0
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39701642
@marqusG - Yes the code in the tutorial is wrong which is why I said he needed the setFetchMode() line (which he has commented) and then to use the fetch() method.

An alternative is to use the fetchAll() method which will take the arguments he's used:

while($rowObj=$STH->fetchAll(PDO::FETCH_CLASS,'secret_person',array($i))){

Open in new window

The $i doesn't necessarily need to be increased. As it stands the code will just pass the value of 0 to the class constructor, but the while loop is still needed to loop through the records.
0
 
LVL 30

Expert Comment

by:Marco Gasi
ID: 39701657
Thanks for the explanation, Chris. Mmmmhh, how can i give you some points now? ;)
However, it seems rgb192 can simply replace $STH->fetch with $STH->fetchAll, isn't it?
This should solve the problem.
0
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39701666
Yup - that would prevent his original error!
Although the while loop sets a variable called $rowObj but inside the loop he tried to access $obj, so there's another error waiting to happen :)

while($rowObj=$STH->fetch(PDO::FETCH_CLASS,'secret_person',array($i))){
    echo $obj->addr.'<br>';

Open in new window

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 30

Expert Comment

by:Marco Gasi
ID: 39701678
Good eye!
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39701748
I just looked back at the PDO article and was somewhat surprised at the number of comments indicating that it contained defective code.   I think upon seeing that, I might have turned away!
0
 

Author Comment

by:rgb192
ID: 39705620
please tell me what line was the error and possible replacements because I am a pdo beginner.

For example
replace this line(s):
code here

with
this line(s):
code here








output of
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28311998.html#a39701428

0: stdClass Object ( [name] => cathy [addr] => 9 dark and twisty road [city] => cardiff ) 1: stdClass Object ( [name] => cathy [addr] => 9 dark and twisty road [city] => cardiff ) 2: stdClass Object ( [name] => cathy [addr] => 9 dark and twisty road [city] => cardiff ) 3: stdClass Object ( [name] => Cathy [addr] => 9 twisty and dark [city] => Cardiff )
0
 
LVL 30

Assisted Solution

by:Marco Gasi
Marco Gasi earned 250 total points
ID: 39705625
Replace these two lines:

while($rowObj =  $STH->fetch(PDO::FETCH_CLASS, 'secret_person', array($i))) {  
    echo $obj->addr.'<br>';

Open in new window


with these lines

while($rowObj=$STH->fetchAll(PDO::FETCH_CLASS,'secret_person',array($i))){
    echo $rowObj->addr.'<br>';
0
 
LVL 42

Assisted Solution

by:Chris Stanyon
Chris Stanyon earned 125 total points
ID: 39706452
Actually, if you're using fetchAll, then you loop through an array with foreach, not with a while() loop:

fetch() grabs the next row, so you need a while() loop to get data record by record
fetchAll() grabs all the rows into an array, so you loop through the array with foreach()

$results = $STH->fetchAll(PDO::FETCH_CLASS, 'secret_person', array($i));
//$results is now an array of 'secret_person' objects
foreach ($results as $person):
   var_dump($person);
   echo $person->addr;
endforeach;

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39707456
@ChrisStanyon: +1.

@rgb192: The examples in this article show how it's done.  I think I've recommended the article to you before, but if not, have a read of the PDO samples.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/PHP_Databases/A_11177-PHP-MySQL-Deprecated-as-of-PHP-5-5-0.html
0
 

Author Comment

by:rgb192
ID: 39717908
I think this is marqus' code

<?php
//  print_r(PDO::getAvailableDrivers());
$host = 'hostedresource.com';
$user=$dbname = 'user';
$pass = 'Password';

class secret_person{
  public $name;
  public $addr;
  public $city;
  public $other_data;
  
  function __construct($other=''){
    $this->addr=preg_replace('/[a-z]/','x',$this->addr);
    $this->other_data=$other;
  }
}




# connect to the database
try
{
  $pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); 
  // SET PDO TO TELL US ABOUT WARNINGS OR TO THROW EXCEPTIONS
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql='SELECT name,addr,city from test';
    $pdos = $pdo->query($sql);
}
catch(PDOException $exc)
{
    var_dump($exc);
    trigger_error($exc->getMessage(), E_USER_ERROR);
}
// SHOW THE RESULTS OF THE QUERY
var_dump($pdos);

// DETERMINE HOW MANY ROWS OF RESULTS WE GOT
$num = $pdos->rowCount();

// ITERATE OVER THE RESULTS SET TO SHOW WHAT WE FOUND
echo "USING PDOStatement::FetchAll(PDO::FETCH_OBJ): ";
echo "<br/>" . PHP_EOL;
while($rowObj=$STH->fetchAll(PDO::FETCH_CLASS,'secret_person',array($i))){
    echo $rowObj->addr.'<br>';
    // ROW BY ROW PROCESSING IS DONE HERE
    foreach ($row as $key => $obj)
    {
        echo "$key: ";
        print_r($obj);
        echo PHP_EOL;
    }
}

Open in new window


object(PDOStatement)#2 (1) { ["queryString"]=> string(31) "SELECT name,addr,city from test" } USING PDOStatement::FetchAll(PDO::FETCH_OBJ):

Fatal error: Call to a member function fetchAll() on a non-object in C:\wamp\www\oop-beg\pdo9a.php on line 46



what I think was Chris' code

<?php
//  print_r(PDO::getAvailableDrivers());
$host = 'hostedresource.com';
$user=$dbname = 'user';
$pass = 'Password';

class secret_person{
  public $name;
  public $addr;
  public $city;
  public $other_data;
  
  function __construct($other=''){
    $this->addr=preg_replace('/[a-z]/','x',$this->addr);
    $this->other_data=$other;
  }
}




# connect to the database
try
{
  $pdo = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); 
  // SET PDO TO TELL US ABOUT WARNINGS OR TO THROW EXCEPTIONS
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql='SELECT name,addr,city from test';
    $pdos = $pdo->query($sql);
}
catch(PDOException $exc)
{
    var_dump($exc);
    trigger_error($exc->getMessage(), E_USER_ERROR);
}
// SHOW THE RESULTS OF THE QUERY
var_dump($pdos);

// DETERMINE HOW MANY ROWS OF RESULTS WE GOT
$num = $pdos->rowCount();

// ITERATE OVER THE RESULTS SET TO SHOW WHAT WE FOUND
echo "USING PDOStatement::FetchAll(PDO::FETCH_OBJ): ";
echo "<br/>" . PHP_EOL;
$results = $STH->fetchAll(PDO::FETCH_CLASS, 'secret_person', array($i));
//$results is now an array of 'secret_person' objects
foreach ($results as $person):
   var_dump($person);
   echo $person->addr;
endforeach;

Open in new window



object(PDOStatement)#2 (1) { ["queryString"]=> string(31) "SELECT name,addr,city from test" } USING PDOStatement::FetchAll(PDO::FETCH_OBJ):

Fatal error: Call to a member function fetchAll() on a non-object in C:\wamp\www\oop-beg\pdo9b.php on line 46
0
 
LVL 30

Accepted Solution

by:
Marco Gasi earned 250 total points
ID: 39717952
In the first snippet you should use

$pdos->fetchAll

instead of $STH

In teh second you're creating an object this way

$pdo = new PDO...

then you print var_dump($pdos)

using an 's' which was present in the first snippet but not in the second and lastly you use newly my suggestion excerpt from my example and pasting my code within another code without change what had to be changed: I used $STH as object and you are using $pdos once and $pdo later.

I think you're doing too mutch questions simultaneoulsy and I fear we are a bit confused: you're merging different suggestions without following one step by step until the ultimate solution.

Personally, I suggest you to leave all these questions and to reopen a new question starting by a the first problem you have to solve. Once you got a solution, go on to the next question.

These are my two cents at this point.
0
 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 125 total points
ID: 39718038
Keeping the variable names straight is one of the important things a programmer must do.  If you call it "pigwhistle" in one place, you have to call it "pigwhistle" in all the places.  The advantage of choosing one example to learn from, and not trying to integrate several examples, is that (assuming the chosen example works) you can follow the variable names through the script to see how the variables are used in each case.
0
 

Author Closing Comment

by:rgb192
ID: 39738108
I think the best answer is the Marqus telling me that I need $pdos not $sth in the examples because it showed me I maid the same mistake twice.

Thanks
0
 

Expert Comment

by:enas ellithy
ID: 41642264
i have same problem when i open inedx.php
i see this statment
Warning: PDOStatement::execute() expects parameter 1 to be array, string given in C:\xampp\htdocs\PHP_Course\eCommerce\1\admin\index.php on line 23
code in line 23
 $sth->execute($sql);
// This Code where the error
$sql = "SELECT `Username`,`Password` FROM `users` WHERE `Username` = '".$username." ' AND `Password` = '".$password." ' ";
        $sth = $db->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
        $sth->execute($sql);
        $count = $sth->rowCount();
        echo $count;
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
This article discusses four methods for overlaying images in a container on a web page
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to count occurrences of each item in an array.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now