PHP PDOStatement::fetchAll returned array contains resource? - php

i'm getting data out of a oracle database:
My code is really simple
$stmt = $con->prepare($query);
$stmt->execute($data);
$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
PHP gives me a resource ID for very long strings in $res.
I want them as a string not a resource ID.
So i can set
$con->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
But now all values are Strings. Not just the resource ones.
Is there a way to achieve this?
(Yes i know that resource IDs are maybe better, but i want it as a string in this case)

The general rule is to use native drivers like PHP OCI8 instead of the limited PHP PDO interface. With OCI8 you can do things like:
while (($arr = oci_fetch_array($s, OCI_ASSOC))) {
$arr = oci_fetch_array($s, OCI_ASSOC+OCI_RETURN_LOBS);
echo $arr['BLOBDATA']; // do something with the LOB
unset($arr); // free PHP's memory before fetching the next LOB.
}
Check out the PHP manual pages or the LOB chapter http://www.oracle.com/technetwork/topics/php/underground-php-oracle-manual-098250.html

Related

postgres stored procedure json error

So I'm making a application where I want a json string to display(for now). I call a stored procedure with php(which works) and that stored procedure returns a row.
The problem is that the record/row that is returned has to be a json string. For that I use php:
$verbinding = pg_connect("host=**** port=**** dbname=*** user=******* password=****");
$query = 'SELECT to_json(function_name(parameter))';
$contests = pg_query($query);
if(json_decode($contests)) {
echo 'succeeded';
} else {
echo 'failed';
}
Now my code always returns failed and I don't know why or how can I fix this. Thank you in advance for your help!
This:
$contests = pg_query($query);
json_decode($contests)
is nonsensical. If you replace json_decode with a print statement you will see why.
Per the manual the return value of pg_query is:
A query result resource on success or FALSE on failure.
and if you look at the examples, you will see some basic usage, where you will see that you need to use pg_fetch_row or similar to access the results.
This makes sense given that a query result can have multiple rows and multiple values per row.
The "See also" section of the documentation link above points you at the functions you need.
In this case I suggest using pg_fetch_result (see the sidebar).
While you're at it some basic error handling would be wise.
I also strongly suspect you're failing to use bind parameters, exposing yourself to SQL injection. Use pg_query_params.
Here's a starting point for you. It's untested, and I don't really use PHP, but it should give you an idea where you're going wrong:
$query = 'SELECT to_json(function_name($1))';
$contests = pg_query_params($query, array($somevariable))
or die(pg_last_error());
$json = pg_fetch_result($contests, 0, 0);
if(json_decode($json)) {
# ....
}
Now, seriously, go read the manual.

Assign MySQL database value to PHP variable

I have a MySQL Database Table containing products and prices.
Though an html form I got the product name in a certain php file.
For the operation in this file I want to do I also need the corresponding price.
To me, the following looks clear enough to do it:
$price = mysql_query("SELECT price FROM products WHERE product = '$product'");
However, its echo returns:
Resource id #5
instead a value like like:
59.95
There seem to be other options like
mysqli_fetch_assoc
mysqli_fetch_array
But I can't get them to output anything meaningful and I don't know which one to use.
Thanks in advance.
You will need to fetch data from your database
$price = mysql_query("SELECT price FROM products WHERE product = '$product'");
$result = mysql_fetch_array($price);
Now you can print it with
echo $result['price'];
As side note I would advise you to switch to either PDO or mysqli since mysql_* api are deprecated and soon will be no longer mantained
If you read the manual at PHP.net (link), it will show you exactly what to do.
In short, you perform the query using mysql_query (as you did), which returns a Result-Resource. To actually get the results, you need to perform either mysql_fetch_array, mysql_fetch_assoc or mysql_fetch_object on the result resource. Like so:
$res = mysql_query("SELECT something FROM somewhere"); // perform the query on the server
$result = mysql_fetch_array($res); // retrieve the result from the server and put it into the variable $result
echo $result['something']; // will print out the result you retrieved
Please be aware though that you should not use the mysql extension anymore; it has been officially deprecated. Instead you should use either PDO or MySQLi.
So a better way to perform the same process, but using for example the MySQLi extension would be:
$db = new mysqli($host, $username, $password, $database_name); // connect to the DB
$query = $db->prepare("SELECT price FROM items WHERE itemId=?"); // prepate a query
$query->bind_param('i', $productId); // binding parameters via a safer way than via direct insertion into the query. 'i' tells mysql that it should expect an integer.
$query->execute(); // actually perform the query
$result = $query->get_result(); // retrieve the result so it can be used inside PHP
$r = $result->fetch_array(MYSQLI_ASSOC); // bind the data from the first result row to $r
echo $r['price']; // will return the price
The reason this is better is because it uses Prepared Statements. This is a safer way because it makes SQL injection attacks impossible. Imagine someone being a malicious user and providing $itemId = "0; DROP TABLE items;". Using your original approach, this would cause your entire table to be deleted! Using the prepared queries in MySQLi, it will return an error stating that $itemId is not an integer and as such will not destroy your script.

Quickly put all data from an SQL query into an array with PHP

I'm using something like the following PHP code to put all data from a query into an array:
<?php
$results = array();
$q = odbc_exec("SELECT * FROM table");
while ($row = odbc_fetch_array($q)) {
$results[] = $row;
}
?>
This works fine, but it is very slow when the query contains thousands of rows.
My question is, is there any way in PHP to dump all the data into an array without having to loop through each record one by one?
NOTE: Using MS SQL Server for the database.
You could try using mssql functions instead of odbc, but its unlikely to make a large difference.
With the way drivers work, the result set is an iterator handle to the result data itself. In some cases, php doesn't actually get the data until the row is requested by php. Unless there is a fetch all available in the driver, looping through all the rows is generally your only option.
If you don't need all the columns, you could limit the data being transfered by specifing only the columns you actually need.
Specifying the cursor_type in odbc_connect made odbc fetching much quicker.
$conn = odbc_connect($dsn, $user, $pass, SQL_CUR_USE_ODBC)
http://aaronsaray.com/blog/2007/08/02/odbc-for-udb-and-php-how-i-increased-performance-by-400/
I was able to find a way to do this with ADOdb (a database abstraction library for PHP) using the GetAll() function:
http://adodb.sourceforge.net/
$results = $DB->GetAll("SELECT * FROM table");
This returns all the rows as a 2-dimensional array.

Mysql query using values in JSONArray

I'm posting a JSONArray.toString() to a php file. The JSONArray contains a set of id values. I want to make a mysql query that only returns rows that have an id contained in the jsonarray. My method below isn't working. Is there another way?
$jsonarray= $_POST["ids"];
$query = mysql_query("SELECT * FROM table WHERE id IN $jsonarray")or die(mysql_error());
It'd help if we had an example of the JSON array, however, you should decode the JSON array into a comma separated list to use with IN.
$jsonarray = $_POST["ids"];
$ids = implode(",", json_decode($jsonarray,true));
$query = mysql_query("SELECT * FROM table WHERE id IN ($ids)")or die(mysql_error());
Also, you should be using mysqli or PDO_MySQL for new development:
It is recommended to use either the mysqli or PDO_MySQL extensions. It
is not recommended to use the old mysql extension for new development.
A detailed feature comparison matrix is provided below. The overall
performance of all three extensions is considered to be about the
same. Although the performance of the extension contributes only a
fraction of the total run time of a PHP web request. Often, the impact
is as low as 0.1%.
Related Reading:
http://php.net/manual/en/mysqlinfo.api.choosing.php
http://www.php.net/manual/en/mysqlinfo.library.choosing.php
echo out the contents of $jsonarray and you will see the error when you check the syntax of the MySQL query

Get MySQL Query Results as Their Native Data Type?

I have tried fetching MySQL query results using mysql_fetch_row() and mysql_result() and numeric values are being returned as strings.
Is there any way to fetch the data as its datatype stored in the table?
The application will be querying many different queries so I will be unable to cast the values as the intended datatype on a 1 by 1 basis.
I don't think getting data in their native datatypes (i.e. anything else that strings) can be done in PHP 5.2...
In PHP 5.3, it becomes possible, if I remember correctly, when you are using the new (new as in PHP >= 5.3) mysqlnd (MySQL Native Driver) driver.
After more digging through my bookmarks I found this article about mysqlnd : PDO_MYSQLND: The new features of PDO_MYSQL in PHP 5.3
It says this (quote) :
Advantages of using mysqlnd for PDO
mysqlnd returns native data types when
using Server-side Prepared Statements,
for example an INT column is returned
as an integer variable not as a
string. That means fewer data
conversions internally.
But this is PHP 5.3 only (provided your version of PHP 5.3 is compiled with mysqlnd (and not the old libmysql)), and seems to only be the case for prepared statements :-(
Which doesn't quite help, in your situation, I guess...
And here's another one, still about the new features of mysqlnd, which talks about this for not only prepared statements : PHP: New network traffic, CPU and memory savings with mysqlnd.
Not sure this has been merged into the official mysqlnd driver, though -- best way would be to try ; but it'll still be PHP >= 5.3 only, anyway...
Another solution would be to have, on the PHP-side, some kind of a mapping-system (like an ORM) to convert results coming from the DB to PHP datatypes...
And yes, this is bad if you want to use operators like === and !==, which are type-sensitive...
try this if using mysqli instead of PDO
$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1);
I've implemented this the manual way. It's actually not too bad, just a few lines.
As suggested, call mysqli_fetch_fields() on the resource resulting from your query.
Then from a mapping of the PHP field type numbers to MySQL data types (see industrious work here http://www.php.net/manual/en/mysqli-result.fetch-field-direct.php) you can convert your values from the wide range of database types returned as strings by MySQLi, into the appropriate type in PHP.
How much of a slowdown it is I'm not sure tho.
In addition to Pascal MARTIN's answer, if you use MySQLi prepared statements you will get the data back using native types.
Try this:
<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))");
$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')");
$stmt = $mysqli->prepare("SELECT id, label FROM test WHERE id = 1");
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
printf("id = %s (%s)\n", $row['id'], gettype($row['id']));
printf("label = %s (%s)\n", $row['label'], gettype($row['label']));
?>
The above example will output:
id = 1 (integer)
label = a (string)
You can get more info here:
https://dev.mysql.com/doc/apis-php/en/apis-php-mysqli.quickstart.prepared-statements.html
I wrote a function to circuvent this (for PDO):
/**
* Converts columns from strings to types according to
* PDOStatement::columnMeta
*
* #param PDOStatement $st
* #param array $assoc returned by PDOStatement::fetch with PDO::FETCH_ASSOC
* #return copy of $assoc with matching type fields
*/
function convertTypes(PDOStatement $statement, $assoc)
{
for ($i = 0; $columnMeta = $statement->getColumnMeta($i); $i++)
{
$type = $columnMeta['native_type'];
switch($type)
{
case 'DECIMAL':
case 'TINY':
case 'SHORT':
case 'LONG':
case 'LONGLONG':
case 'INT24':
$assoc[$columnMeta['name']] = (int) $assoc[$columnMeta['name']];
break;
case 'DATETIME':
case 'DATE':
case 'TIMESTAMP':
$assoc[$columnMeta['name']] = strtotime($assoc[$columnMeta['name']]);
break;
// default: keep as string
}
}
return $assoc;
}
Of course the type list are not complete and the conversion is oversimplified, but can be useful for start.

Categories