Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

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

Posted on 2013-12-06
22
Medium Priority
?
2,599 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 31

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 31

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 44

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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 111

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 44

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 111

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 31

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 44

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 31

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 44

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
 
LVL 31

Expert Comment

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

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 31

Assisted Solution

by:Marco Gasi
Marco Gasi earned 1000 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 44

Assisted Solution

by:Chris Stanyon
Chris Stanyon earned 500 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 111

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 31

Accepted Solution

by:
Marco Gasi earned 1000 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 111

Assisted Solution

by:Ray Paseur
Ray Paseur earned 500 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

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Foreword (July, 2015) Since I first wrote this article, years ago, a great many more people have begun using the internet.  They are coming online from every part of the globe, learning, reading, shopping and spending money at an ever-increasing ra…
Introduction This article is intended for those who are new to PHP error handling (https://www.experts-exchange.com/articles/11769/And-by-the-way-I-am-New-to-PHP.html).  It addresses one of the most common problems that plague beginning PHP develop…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.
Suggested Courses

926 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