PHP PDO execute() returning duplicate results - php

For this code:
$title = '0';
$subTitle = '1';
$tableName = 'someString';
$stmt = $dbh->prepare("SELECT `".$title."`, `".$subTitle."` FROM `".$tableName."_data` WHERE `id` = :key");
$stmt->bindValue(':key', '127');
$stmt->execute();
$result = $stmt->fetchAll();
print_r($result);
I get $result as this:
Array
(
[0] => Array
(
[0] => 91651
[1] => 91651 - DESCRIPTION
[2] => 91651 - DESCRIPTION
)
)
When the expected result should be this:
Array
(
[0] => Array
(
[0] => 91651
[1] => 91651 - DESCRIPTION
)
)
When I run the same query in mySQL, it returns the expected result. When it is executed via PHP PDO, it adds a duplicate.
Thanks!

Use fetchAll(PDO::FETCH_ASSOC) instead of fetchAll().

Solved by checking with someone better at databases than myself...
I foolishly named the columns as integer values.
So, what appeared as "duplicate values" was just the fact that the column number and the column name were the same!
In conclusion, I am bad at database structure.

Try to check the fetch_style and fetch_argument and set it to a value you need.
see sample #3:
http://www.php.net/manual/en/pdostatement.fetchall.php
sometimes dep. on your php version/pdo version there is a bug when using bindvalue.
try to avoid that and use sample #3 instead.

You could change to using fetch() instead of fetchAll(), that will return one row. But I'd just ensure in the database that id is unique.

Related

Mysql PDO return double result on select [duplicate]

I'm new to using $pdo statements so might be something simple I haven't yet read on php.net. I'm receiving duplicate results when querying the database.
Result:
[0] => Array
(
[umeta_id] => 31
[0] => 31
[user_id] => 2
[1] => 2
[meta_key] => fbmeta
[2] => fbmeta
[meta_value] => someMetaValueStuff;
[3] => someMetaValueStuff;
)
The query is quite simple:
function getData(){
global $pdo;
$query = $pdo->prepare('SELECT * FROM usermeta WHERE meta_key = "fbmeta" LIMIT 0,30');
$query->execute();
return $query->fetchAll();
}
print_r( getData() );
The problem is that the named keys (umeta_id, user_id, meta_key, meta_value) DO exist, the numeric keys do not. How come the query returns these? And how do I prevent them from even being returned?
It's not duplicates, it's just the current FETCH_MODE you're using. To get as associative keys only you need to specify as such; by default it fetches as both.
Use like so:
$query->fetchAll(PDO::FETCH_NUM); // to fetch with numeric indexes
$query->fetchAll(PDO::FETCH_ASSOC); // to fetch with associative indexes
fetchAll docs
fetch docs
This is not duplicate data fetchAll returns data in numeric array as well as associative array.
See the Docs
Use this for retrieving only associative array
return $query->fetchAll(PDO::FETCH_ASSOC);
seems to do the trick for me. Put this on top
use Illuminate\Database\Events\StatementPrepared;
when ever fetching include pdo::fetch_assoc
return($pdo->fetchAll(\PDO::FETCH_ASSOC));

PHP array_intersect or in_array then MYSQL

Need to find if two arrays match, and then where they match pull data from the mysql row in which they match. Should I use
$sql = "SELECT * FROM around";
$resultsd = $conn->query($sql);
foreach($resultsd as $rowd) {}
if (array_intersect($ar1, $ar2)) {
$sword[] = $rowd['TIM'];
}
or should I use
if (in_array($ar1, $ar2)) {
$sword[] = $rowd['TIM'];
}
Getting the arrays like:
$ar1[] = $rowd['nim'];
$ar2[] = $rowd['nim'];
Then how does one go about pulling the specific row that they match at?
I am seeing that they match, and printing out the array's okay:
Array ( [0] => dcbabcbded ) Array ( [0] => fafeafaebee [1] => afabfdefcbb [2] => dcbabcbded
But when I trying a echo the mysql data where they match I fail:
Array ( )
i would go with sql IN clause.
You have an array of customer names: $a = array('john','rob','paul');
implode array $nms = join(',',$a);
Make sql: 'SELECT * FROM tabl WHERE name IN ('.$nms.')';
do the array intersection first (or what you just have to..) to have an array of needed names.
use $new = array_intersect(Array ( [0] => dcbabcbded ), Array ( [0] => fafeafaebee [1] => afabfdefcbb [2] => dcbabcbded)) : then make valid sql as stated in my answer above.
If u are sure you've allways have array intersenct with one or none values, then make sql just with first array element: $ar[0] using sql WHERE clause.

PHP multi-dimensional array value as index

aside from doing the actual work of iterating through an associative array, pushing a value into a new array and setting that equal the array of remaining fields, is there an array function built into PHP that would do something like this?
if so, what is it?
i would be changing the following:
Array
(
[0] => Array
(
[0] => TEST //Name (Database column name
[1] => 12430 //ID (Database column name
[2] => Y //Save (Database column name
[3] => 100 //Wert (Database column name
)
into something like this:
Array
(
[12430] => Array
(
[Name] => TEST
[Save] => Y
[Wert] => 100
)
i work with while-loop:
....
while( $row = mysql_fetch_assoc($ergebnis) ) {
....
}
I think that you are going to have to iterate through the array. There may be a function here that could shorten the code by about a line, but I doubt it will make a noticeable difference to the readability and efficiency of your code.
So I would iterate through the array if I were your, quite short and simple.
$new_array = array();
while( $row = mysql_fetch_assoc($ergebnis) ) {
$new_array[$row[1]] = $row;
unset($new_array[$row[1]]);
}
Note that the mysql_ functions have been deprecated in PHP and you should be using mysqli_ or PDO instead, as it is more stable and secure.
Also, as #CBroe said, the mysql_fetch_assoc function will return the second part of your desired result already. The equivalent in PDO would be $query->fetch(PDO::FETCH_ASSOC);
Good luck!
Alter your query and add GROUP BY ID at the end.

PHP class array question

For some reason my array I am returning is not what I expect. Could someone explain to me why I am getting the current results, and what I can do to fix it? Here is the code in question:
public static function getProduct($_row, $_value)
{
$stmt = _DB::init()->prepare("SELECT pid, name, quantity, price, cost
FROM products
WHERE $_row = ?"
);
if($stmt->execute(array($_value)))
{
while ($row = $stmt->fetch())
return $row;
}
}
$product = Class::getProduct('pid',1);
print_r($product);
When I print the following array I am getting two results per row like so:
Array ( [pid] => 1 [0] => 1 [name] => Boondoggle [1] => Boondoggle [quantity] => 12 [2] => 12 [price] => 9.9900 [3] => 9.9900 [cost] => 12.9900 [4] => 12.9900 ) Boondoggle
I was only wanting to show the associative results. What is wrong with my function?
From the looks of it you are using PDO to communicate with your DBMS. The PDOStatement::fetch() method's first argument is a parameter to tell it what to return. By default it returns each column in both name format and numbered index format to allow iterating through columns easier. To just get the column names as indexes, you can pass it PDO::FETCH_ASSOC to your call. So the fetch statement would look like this:
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)
See here for more details:
http://www.php.net/manual/en/pdostatement.fetch.php
Pass PDO::FETCH_ASSOC to your fetch call:
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
edit: I'm just assuming you're using PDO, of course

PDO acts different on two -very- similar queries

The following block of code works fine (no errors)
$query = "select * from users where username = ?";
$statement = $sql->prepare($query);
echo gettype($statement); // -- This returns 'object'
$statement->bindParam(1, $username);
The following gives:
Fatal error: Call to a member function bindParam() on a non-object in /file.php on line 39
$email = 'fake#email.com';
$query = "select * from users where email = ?";
$statement = $sql->prepare($query);
echo gettype($statement); // -- this returns 'boolean'
$statement->bindParam(1, $email); // -- this is line 39.
Now this is strange.
At my local machine, and my remote host, this was never a problem.
This errors only shows up on this new hosting company I am trying out for the month. Could it be a config param when they compiled php?
--------edit--------
While still trying to figure out what's wrong,I found this out.
$query = "select userID, username from users";
$statement = $sql->prepare($query);
$statement->execute();
$r = $statement->fetchAll(PDO::FETCH_ASSOC);
// display # of rows
echo "Rows returned: " . $statement->rowCount();
// display results array
echo '<pre>'; print_r($r); echo '</pre>';
On a server, I get
Rows returned: 4
Array
(
[0] => Array
(
[userID] => 1
[username] => lyrae
)
[1] => Array
(
[userID] => 2
[username] => jproffer
)
[2] => Array
(
[userID] => 3
[username] => king
)
[3] => Array
(
[userID] => 4
[username] => gergy
)
)
Which is correct. Says 4 rows returned and displays the result array. On another server however, I get
Rows returned: 0
Array
(
[0] => Array
(
[userID] => 1
[username] => lyrae
)
[1] => Array
(
[userID] => 2
[username] => jproffer
)
[2] => Array
(
[userID] => 3
[username] => king
)
[3] => Array
(
[userID] => 4
[username] => gergy
)
)
Thus, it seems also that PDOStatement::rowCount() does not work on a sever but works on another.
Read this: $statement->closeCursor()
PDOStatement::closeCursor() frees up the connection to the server so that other SQL statements may be issued
Are you using the same database on the server where you say you don't have this issue?
Found a solution to the problem.
This is the entire block of code..
// check if username exists
$query = "select * from users where username = ?";
$statement = $sql->prepare($query);
$statement->bindParam(1, $username);
$statement->execute();
// check if email exists
$sql2 = new PDO('mysql:host=localhost; dbname=db', 'username', 'pw');
$query = "select * from users";
$statement = $sql2->prepare($query);
echo gettype($statement);
#$statement->bindParam(1, $email);
So for some reason, I have to create a new instance of PDO. what's strange is that on 2 other servers, I don't have to do this.
And upon further looking, i found that PDO::Prepare raises an PDOExeption.
Here it is:
SQLSTATE[HY000]: General error: 2014 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.
Array
(
[0] => HY000
[1] => 2014
[2] => 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.
)
Maybe it'll help someone in the future :)
Is $email undefined? You could try a var_dump($email) too see what it says. Good luck.
Have you tried putting the $email= line below the bindParam (but before you do the execute)? bindParam passes the parameter by reference so you can execute as query, change the value of the variable and execute again.
I think though that it's probably a PHP set up error. I've heard people saying PDO had a lot of bugs before PHP 5.3, so maybe see if you can get PHP up to the latest version?
Have you also tried swapping the two queries around? Maybe something breaks after you run one query.
I'd better recommend using this:
$email = 'fake#email.com';
$query = "select * from users where email = ?";
$statement = $sql->prepare($query);
$statement->execute(array($email));
No BindParam use is needed here.
I had same problem with
echo "Rows returned: " . $statement->rowCount();
I got -1 rows, lol. My database is INFORMIX and searching web i found
that rowCount(); returns only affected rows in a DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
With a SELECT statement you need to use function
$statement->fetchColumn();
read it here: http://www.phpbuilder.com/manual/en/function.pdostatement-rowcount.php

Categories