store objects in $_GET - php

how can i store an object in the $_GET array in PHP. i want to pass an object containing database information from one page to another page via the $_GET array, so there would be no need to access the database again.

To pass any sort of object, you'd have to serialize it on one end, and unserialize it on the other end.
But note that this will not work for database connections themselves : the connection to the database is automatically closed when a PHP script ends.
You could pass some connection informations, like login, host, or stuff like that (but that would not be a good idea -- quite not safe to expose such critical informations !) ; but you cannot pass a connection resource.

Really, you should be passing data from one page to another via the $_SESSION variable instead, if possible. That is what sessions are for. Ideally just store an id in the session and look up the data on each page. If you do use $_SESSION then it is as simple as ...
$_SESSION['myarray'] = $myarrayobject;
$_SESSION['someotherthing'] = 42;
If you have to use $_GET, then I would recommend just passing an id of some kind, then re-looking up the data on each page refesh.
Keep in mind, it would be easy for a malicious user to change the values that are sent via $_GET between pages, so make sure there is nothing that can be abused in this information.

You would need to serialize it to text (possibly using json_encode), then generate a URL that included it in the query string (making sure that it was urlencoded)

That's very bad idea.
Database were invented to serve each request, while query string were designed to pass only commands and identificators, not tons of data between browser and server

Instead of using get, another possibility to pass something from one page to another is to use the $_SESSION array and then to unset that variable on the other side whenever you're done with it. I've found that to be a pretty good way to do this.
Like everyone else has said though, passing database information can be a bad idea, assuming the information you're passing isn't something like username, first name, etc. If that's what you're passing when you say "database information" then I would store all that stuff in the $_SESSION variable and then destroy their session when they log out. Don't store the entire connection or something.

As has been said before you should avoid (mis-)using GET parameters as a "cache" for overly complex and loooong data.
On the other hand your question is vague enough to assume that you want to transmit only a few values. And your "second" script needs nothing else from the database, in fact it might not even have to check if those values came from a database at all.
In this case extract the values from your database result and append them as parameters to the url. Try to make the parameter list as simple as possible but yet unambiguous. http_build_query() can help you with that.
But keep in mind that you want to keep GET operations idempotent as described in http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html.
if ( isset($_GET['a'], $_GET['b'], $_GET['c']) ) {
// this doesn't care about the values in the database at all.
echo 'product: ', $_GET['a'] * $_GET['b'] * $_GET['c'], "\n";
}
else {
$pdo = new PDO("mysql:host=localhost;dbname=test", 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// let's make it a self-contained example (and extra constly) by creating a temproary table ...
$pdo->exec('CREATE TEMPORARY TABLE foo (id int auto_increment, a int, b int, c int, primary key(id))');
// ... with some garbage data
$stmt = $pdo->prepare('INSERT INTO foo (a,b,c) VALUES (?,?,?)');
for($i=0; $i<10; $i++) {
$stmt->execute(array(rand(1,10), rand(1,10), rand(1,10)));
}
foreach( $pdo->query('SELECT a,b,c FROM foo', PDO::FETCH_ASSOC) as $row) {
printf('%s<br />',
http_build_query($row),
join(' * ', $row)
);
}
}

Related

SELECT WHERE = sybol dont return data

a have an sqlite table
CREATE TABLE "lib" (
"id" INTEGER UNIQUE,
"addr" TEXT UNIQUE,
"data" TEXT,
PRIMARY KEY("id")
)
testing dataset contains:
...
1 arara arararar test
2 unit=comp comp test
...
I use code next to test requests
<? $db = new PDO('sqlite:main.db') or die('Unable to open database');
echo ("qry: ".$_SERVER["QUERY_STRING"]."<br>");
foreach ($db->query("SELECT * FROM lib WHERE addr='".$_SERVER["QUERY_STRING"]."'", PDO::FETCH_ASSOC/*_NUM*/) as $row) {
//echo($row[0].'<br>');
echo($row['addr'].'<br>');
echo($row['data'].'<br>');
}
$db = null; ?>
so, when I do script.php?arara it returns
qry: arara
arara
arararar test
but, when I do script.php?unit=comp it returns no data (just QUERY_STRING)
qry: unit=comp
what wrong with my code?
upd:
this question is not about security
php modified for PDO prepare, now its return no data with any request
<? $db = new PDO('sqlite:main.db') or die('Unable to open database');
echo ("qry: ".$_SERVER["QUERY_STRING"]."<br>");
$qry=$db->prepare("SELECT * FROM lib WHERE addr='?'");
$qry->execute(array($_SERVER["QUERY_STRING"]));
foreach ($qry as $row) {
//foreach ($db->query("SELECT * FROM lib WHERE addr='".$_SERVER["QUERY_STRING"]."'", PDO::FETCH_ASSOC/*_NUM*/) as $row) {
//echo($row[0].'<br>');
echo($row['addr'].'<br>');
echo($row['data'].'<br>');
}
$db = null; ?>
what wrong with my code?
... sadly quite a lot.
I've never seen someone inject the QUERY_STRING straight into a query. How easily corruptable would this string be? If I wanted to inject some malicious sql I just have to write it in. If I make a mistake then the query won't return anything. If I add a new parameter in the future because I want more than a single param then the query fails.
The malicious sql is the most dangerous problem here, the other's are about code maintainability and still very important. Check out this
https://bobby-tables.com/
and this
https://www.w3schools.com/php/php_mysql_prepared_statements.asp
You need to parse the query string so you can check and sanitise the data. Php has an in-built function for this:
https://www.php.net/manual/en/function.parse-str.php
You then should be binding the data in the prepared statement you have now read about.
I don't know if you're in charge of the script calling this, but it seems like POST data would be better for this. GET parameters are visible and stored in web server logs, so you have a security vulnerability with potential personal data. You also then won't need to worry about url_encoding/decoding the string.
//EDIT
to be fair, using PHP's parse_str with decode the url anyway, so that at least will take care of that issue if you can't convert it to post

Laravel store session in cookie

I have a website where the front page contains a search form with several fields.
When the user performs a search, I make an ajax call to a function in a controller.
Basically, when the user clicks on the submit button, I send an ajax call via post to:
Route::post('/search', 'SearchController#general');
Then, in the SearchController class, in the function general, I store the values received in a session variable which is an object:
Session::get("search")->language = Input::get("language");
Session::get("search")->category = Input::get("category");
//I'm using examples, not the real variables names
After updating the session variable, in fact, right after the code snippet shown above, I create (or override) a cookie storing the session values:
Cookie::queue("mysite_search", json_encode(Session::get("search")));
And after that operation, I perform the search query and send the results, etc.
All that work fine, but I'm not getting back the values in the cookie. Let me explain myself.
As soon as the front page of my website is opened, I perform an action like this:
if (!Session::has("search")) {
//check for a cookie
$search = Cookie::get('mysite_search');
if($search) Session::put("search", json_decode($search));
else {
$search = new stdClass();
$search->language = "any";
$search->category = "any";
Session::put("search", $search);
}
}
That seems to be always failing if($search) is always returning false, and as a result, my session variable search has always its properties language and category populated with the value any. (Again: I'm using examples, not the real variables names).
So, I would like to know what is happening here and how I could achieve what I'm intending to do.
I tried to put Session::put("search", json_decode($search)); right after $search = Cookie::get('mysite_search'); removing all the if else block, and that throws an error (the ajax call returns an error) so the whole thing is failling at some point, when storing the object in the cookie or when retieving it.
Or could also be something else. I don't know. That's why I'm here. Thanks for reading such a long question.
Ok. This is what was going on.
The problem was this:
Cookie::queue("mysite_search", json_encode(Session::get("search")));
Before having it that way I had this:
Cookie::forever("mysite_search", json_encode(Session::get("search")));
But for some reason, that approach with forever wasn't creating any cookie, so I swichted to queue (this is Laravel 4.2). But queue needs a third parameter with the expiration time. So, what was really going on is that the cookie was being deleted after closing the browser (I also have the session.php in app/config folder set to 'lifetime' => 0 and 'expire_on_close' => true which is exactly what I want).
In simple words, I set the expiration time to forever (5 years) this way:
Cookie::queue("mysite_search", json_encode(Session::get("search")), 2592000);
And now it seems to be working fine after testing it.

Cache data from MySQL in PHP?

Is it possible to ask for all data in my database and make objects from it and save it into an array or something, so I just need to call the database once and afterwards I just use my local array? If yes, how is it done?
public function getAllProjects(){
$query="SELECT * FROM projects";
$result=mysql_query($query);
$num=mysql_numrows($result);
while ($row = mysql_fetch_object($result)) {
// save object into array
}
}
public function fetchRow($row){
include("Project.php");
$project = new Project();
$id=$row->id;
$project->setId($id);
$title=$row->title;
$project->setTitle($title);
$infos=$row->info;
$project->setInfo($infos);
$text=$row->text;
$project->setText($text);
$cate=$row->category;
$project->setCategory($cate);
return $project;
}
If I have for example this code. How do i store the objects correctly into an array, where I grab the data from? And why can't I make more than one object of type "Project"?
Let's ignore the fact that you will run out of memory.
If you have everything in an array you will no longer have the functionalities of a relational database.
Try a search over a multi megabytes, multi dimensional array in php and be prepared for a extended coffee break.
If you are thinking in doing something like that is because you feel that the database is slow... You should learn about data normalization and correct use of indexes then.
And no NoSQL is not the answer.
Sorry to pop your balloon.
Edited to add: What you CAN to is use memcache to store the final product of some expensive processes. Don't bother storing the result of trivial queries, the internal cache of mysql is very optimized for those.
You should use the $_SESSION vars in php, To use them, add a session_start() at the beginning of your code. Then you can set vars with $_SESSION['selectaname'] = yourvar
Nothing prevent you to make a sql query like "SELECT username FROM users WHERE id = 1" and then set a $_SESSION['user'] = $queryresult
Then you'll have this :
echo $_SESSION['user'];
"mylogin"

How to pick up the database name and table name from the URL in PHP?

I am new to PHP.
I need a help regarding the methods of extracting DB name and table name from the given URL name.
For example, let's say, I have an URL like the one below:
/test.php?db=...&table=.../
How to extract the DB name and table name from this URL using PHP and use the result for other query purposes.
If you mean how to parse an existing URL for it's parameters:
parse_url() and parse_str() will help you strip the components of the url. You will primarily be looking at the following
$elements = parse_url($url);
$kvps = $elements->query;
$db = parse_str($kvps['db']);
$table = parse_str($kvps['table']);
But, if you mean how to GET variables from the current page before render:
<?php
$dbname = $_GET['db'];
$tablename = $_GET['table'];
?>
And yea, there are major security risks involved in opening up 'direct' access to your database this way. Best to obfuscate / encapsulate / wrap your functions in tasks like index.php&addUser=tim instead of index.php&insert=tim&db=boofar&table=users&dbuser=root&dbpassword=secure.
If you're just learning, what you're doing is fine, as long as you realize why it's wrong. If you're coding for production, you really need an alternate solution.
There are two ways to pass variables or data to another page.
GET (via the URL)
and
POST (usually a form submission)
You can alway get via
$_GET
http://php.net/manual/en/reserved.variables.get.php
or
$_POST
http://nl.php.net/manual/en/reserved.variables.post.php

PHP IF statement not taking variable into account!

I have a tabled view in a while loop, where a user can view information on books.
For example, book ISBN, book name, read status...
Basically, when the user sets their 'readstatus' to 'complete' I want that specific table row to become grey! The logic is very straight forward, however I can't get my IF statement to recognise this:
if ($readstatus == 'complete') {
echo '<tr class="completed">';
}
else if ($readstatus != 'complete') {
echo '<tr class="reading">';
}
I'm obviously doing something wrong here, table content to change if the value of 'readstatus' = 'complete', if not, then output is the default
Why are you using $_GET? Does this information come from an HTML form or a URL etc... ?
I suspect you meant to change $readstatus = $_GET['readstatus']; to $readstatus = $row['readstatus'];.
$_GET is an aray of GET parameters which come from the query string.
$row is a row in your database, so if the information is in the database - which I suspect it is - you want to use $row instead of $_GET.
Try changing $readstatus = $_GET['readstatus']; to $readstatus = $row['readstatus'];
The $_GET function relies on the value being contained in the query string of the URL, and it has nothing to do with the database. I have a hunch you're trying to get the value from the database here and you're using the wrong function to do it.
$_GET['readstatus'] says the value is coming from the browser.
$row['readstatus'] says the value is coming from the database.
You need to decide which should take precedence-- probably the $_GET['readstatus']` because it's what the user wants to change. If that's the case, you need to update your database with the new readstatus before you requery the db for the dataset.

Categories