Best format in php to save mysql result to a file? - php

I'm setting up a caching system in PHP for database queries.
So when a query like "SELECT * FROM table" is called, it either returns the cached results of that query or the results directly from the DB.
$query = "SELECT * FROM table";
[...]
$data = mysql_query($query);
[...]
fwrite($file,json_encode($data));
[...]
The problem is I'm trying to save the query results to a file and I can't find a textual format that works. I've tried json_encode and serialize, and they both return null or 0. Is there a format that will work for this without having to do mysql_fetch_array() and then serialize?
This is the error I get with json, obviously because I haven't converted the result to an array:
Warning: [json] (php_json_encode) type is unsupported, encoded as null

why not:
use native mysql cache?
optimize queries so they work fast and don't need to be cached?

It may not be a perfect solution for the issue you are handling, but I have found Justin Vincent's ezSQL Class to be really handy for working with situations like this. The class includes a caching function, which would satisfy the needs you mentioned in the question above. (Bonuses being that it handles alot of the more obtuse PHP<=>MySQL interactions as well.)

Related

PHP Atlas.ORM returns always the same result

I want to load data from a SQLite database in PHP using Atlas.Orm.
When I run the following snippet, I get a set of 1773 results, but each result is the same!
$atlas = Atlas::new('sqlite:[Path To Database]');
$result = $atlas->select(Stop::class)->fetchRecords();
Can anyone tell me whats wrong here?
After several hours of desperation, I found the issue by myself. The ORM needs the PRIMARY_KEY constant in the corresponding *Table class to be set, otherwise fetching records will fail like this.

Postgresql regexp_matches inside view always returns null when queried from PHP

I have view similar to this one
CREATE OR REPLACE VIEW regexp_test AS (
SELECT regexp_matches(decode('NTB4', 'base64')::text, '(\d+)x')
)
When I query view from pgAdmin, array with single value of 50 is returned, as expected.
SELECT * FROM regexp_test
But when I call the very same query from within PHP via pg_query('SELECT * FROM regexp_test'), nothing is returned.
postgres version 9.5.3,
php version 7.0.3 (same result with 5.6.14)
PHP code is very plain:
<?php
$link = pg_connect('host=localhost port=5432 dbname=test user=postgres password=postgres');
$qry = "SELECT * FROM regexp_test";
$res = pg_query($link, $qry);
while ($row = pg_fetch_row($res)) {
print_r($row);
}
The same query
select e'\\x353078'::bytea;
gives results in different formats in psql:
bytea
----------
\x353078
and in PgAdmin III:
bytea
----------
50x
For the documentation:
The bytea type supports two external formats for input and output: PostgreSQL's historical "escape" format, and "hex" format. Both of these are always accepted on input. The output format depends on the configuration parameter bytea_output; the default is hex. (Note that the hex format was introduced in PostgreSQL 9.0; earlier versions and some tools don't understand it.)
PgAdmin III (and also PgAdmin4) probably for historical reasons sets the value of bytea_output to escape while the default value of the parameter is hex. This can lead to confusion (and as you can see it leads). It seems that pgAdmin should not change the default value of the parameter.
You can change the parameter in your application to get the same behaviour like in PgAdmin:
set bytea_output to escape;
Of course, using encode() is also a good solution.
pg_query returns a result resource.
$result = pg_query('SELECT * FROM regexp_test');
while ($row = pg_fetch_row($result)) {
echo "$row";
}
pg_query returns false on error
If an error occurs, and FALSE is returned, details of the error can be retrieved using the pg_last_error() function if the connection is valid.
I figured out using encode(decode('NTB4', 'base64'), 'escape') instead of typecast decode('NTB4', 'base64')::text fixed problem.
So test view now looks like this:
CREATE OR REPLACE VIEW regexp_test AS (
SELECT regexp_matches(encode(decode('NTB4', 'base64'), 'escape'), '(\d+)x')
)
Calling pg_query('SELECT * FROM regexp_test') now returns expected result - single row/field with '{50}' in it.

PHP PDO - Understanding for beginners

I've read through PHP PDO Book and now have some basic questions:
If i understood correctly, i'll have to use begin_transaction() in order to turn off autocommit. If i am okay with autocommit, i am always good to go with a simple query()Is this correct?
Did i get it right, that there is basically no difference between query() and exec(), except of the above asked topic?
I made a query like this one:
foreach ($db->query('SELECT * from user') as $row) {
$row = json_encode($row);
echo $row;
}
Which returns a JSON Object:
{
"alias":"tk",
"0":"tk",
"password":"pw",
"1":"pw",
}
This is basically correct, however, why is each value returned twice, once with my chosen keyword and another time with an Integer key?
why is each value returned twice, once with my chosen keyword and another time with an Integer key?
The array has the values both with the column names as keys, and the column ordinals too. So you could access the values from the result set by using the number of which column you want. (of course, that does not seem to be of too much use with a select * statement...)
You can affect this behaviour with PDOStatement::setFetchMode(). The constants starting with PDO::FETCH_ are applicable here. Their documentation can be found here

JSON from SQL Table get double result

first of all i have to tell you that it is my first step on php and JSON.
I decided to use JSON to get value from a customer SQL Table.
I get my results using this script :
mysql_connect($config['mysql_host'],$config['mysql_user'],$config['mysql_pass']);
//select database
#mysql_select_db($config['db_name']) or die( "Unable to select database");
mysql_query('SET CHARACTER SET utf8');
$fet=mysql_query('select * from vehicule');
$json = array();
while($r=mysql_fetch_array($fet)){
$json[] = $r;
}
header('Content-Type: application/json');
echo $json_data=json_encode($json);
Everything is ok, exept that my JSON results looks like :
0 = 462;
1 = "Hyundai ix20 crdi 115 panoramic sunsation";
10 = 1346450400;
11 = "462-Hyundai-ix20-crdi-115-panoramic-sunsation";
12 = 462;
...
id = 462;
kilometrage = 14400;
marque = 4;
modele = 137;
motorisation = 2;
ordre = 462;
prix = 17500;
puissance = 6;
titre = "Hyundai ix20 crdi 115 panoramic sunsation";
url = "462-Hyundai-ix20-crdi-115-panoramic-sunsation";
...
I have result of the table in 2 versions : one with 0:value, 1:value, 2... and the other one using the table key, how can i print only the second one ?
By the way can someone give me link so i can know by what i have to replace mysql which is think out of date ? (i'm a beginner few hours using PHP)
Thank you very much !
You have two different issues happening here. One is outright causing the issue you are seeing, and the other is a bad practice mistake that will leave you wide open for trouble in the long run.
The first issue is the one you're asking about. The mysql_fetch_array function (see the Docs here) expects a minimum of one input (the result input) that you are providing. It also has a second, optional input. That optional input defaults to MYSQL_BOTH, which returns an associative array with the results available both through keys (column names) and their indexes. Which is to say, that if you select the column 'id', you get it's value in both $array[0] and $array['id']. It's duplicated, and thus the JSON process carries over the duplication. You need to provide a second value to the function, either MYSQL_ASSOC to get $array['id'] or MYSQL_NUM to get $array[0].
Your second issue is the choice of functions. You're using the 'raw' mysql functions. These have been depreciated, which is a technical term that means 'these functions are no longer supported, but we've left them in to give you time to fix legacy code'. For legacy, read 'old'. Those functions will be going away soon, and you need to upgrade to a better option -- either the mysqli functions, or the PDO class. I strongly recommend the PDO class, as once you learn it it's easy to learn and has the advantage of being more portable. Whichever set you go with, you need to learn to use prepared statements as both a performance and security issue. Right at the moment, you're working with 'raw' statements which have a history of being very easy to interfere with via what's called an 'injection attack'. You can see a fictionalized example of such an attack here, and there are plenty of articles online about it. These attacks can be incredibly complex and difficult to fight, so using prepared statements (which handle it for you), is strongly recommended. In the specific example you're using here, you don't need to worry about it because you aren't including any user inputs, but it's an important habit to get into.

Plain SQL to Codeigniter syntax

I am facing a little trouble with converting this sql to codeigniter syntax. I can use this plain sql and getting results but I have to use return $this->db->query($sql, array($param))->result(); which I guess doesn't return an array (Not sure though, but i keep getting a error "Cannot use object of type stdClass as array in...", and I have no idea if that query can be modified to return an array or any other workaround is available.) Anyway, I guess the best thing to do for me is to follow the CI syntax of query and then use a return $query->result_array(); to get a result array from the query. I know it may be very basic stuff , but somehow I am not able to figure out how to exactly convert this sql to CI syntax. Any help would be appreciated. Thanks. Here is the sql below.
SELECT dirmast.entryID,dirmast.entryTitle,dirmast.entryShortDesc,dirsec.dirsecRefID
FROM dirmast,dirsec
WHERE dirsec.drtext = 'something'
AND dirsec.dirsecRefID = dirmast.entryID
GROUP BY dirsec.dirsecRefID
I think this will do what you want:
$this->db->select('dirmast.entryID,dirmast.entryTitle,dirmast.entryShortDesc,dirsec.dirsecRefID');
$this->db->from('dirmast');
$this->db->join('dirsec','dirsec.dirsecRefID = dirmast.entryID');
$this->db->where('dirsec.drtext','something');
$this->db->group_by('dirsec.dirsecRefID');
If you want your results in an array, you do ->result_array(), if you want it as an object, you do ->result(). Either way, you can use both Active Records and query().

Categories