I'm trying to add some speed performance to a project I'm working on using memcache. However I'm having a problem with the following
public function sql_query($query){
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
$memkey = md5($query);
$get_result = $memcache->get($memkey);
if ($get_result){
return $get_result;
} else {
$q = $this->mysqli->query($query);
$memcache->set($memkey, $q, false, 120) or die ("Failed to save data at the server");
if ($this->mysqli->error){
App::Error($this->mysqli->error);
}
return $q;
}
}
It is certainly putting something into memcached but I get this error when pulling it back out and use it as I would if it wasn't from the cache.
"Warning: mysqli_result::fetch_assoc(): Couldn't fetch mysqli_result"
Am I missing something? I'm sure I've used memcache before in a similar way without any issues.
You can not store all data-types into memcached (and other data-stores), one which most often does not work are resources Docs, for example a database link or a result identifier.
You stored such a value and on another request you pulled it out again. But as the database already is in another state, this resource does not work any longer. You get the error then.
Instead you need to store the result data from the query, that's static data you can put into memcache.
Related
I've been checking on this error with no solutions specific to my code. I have connected to mysql server using the mysqli_connect() call. then passed the connection result to a $_SESSION to have it available over the whole website - as i normally do in all my other projects, But for some reason i keep getting the error:
"mysqli_query(): Couldn't fetch mysqli"
There is the code that generates the error:
if(!isset($_GET['sortBy']))
{
$listSQL = "SELECT * FROM '".$_SESSION['WorkTable']."'";
}
else
{
$listSQL = "SELECT * FROM '".$_SESSION['WorkTable']."' where ".$_GET['sortBy']."='".$_GET['sortBy']."'";
}
//get Contacts From DB
if(!empty(mysqli_query(#$_SESSION['IMWEDBcxn'],$listSQL)))
Here is the connection class code...
if(!empty($cxn))
{
$_SESSION['WorkTable'] = $dbTable;
$_SESSION['IMWEDBcxn'] = $cxn;
}
Anything I'm missing here?
As stated by Ivan Solntsev, do not store a connection handler in a user's session for 2 obvious reasons :
1- Handlers can not be serialized.
2- Anything you store in a user's session (using $_SESSION), would only be available under that user's scope. I suggest you read more about sessions and PHP, $_SESSION is not a way to store data over sessions.
So doing something like :
$connect = mysqli_connect("...");
$_SESSION["dbconnection"] = $connect;
mysqli_query($_SESSION["dbconnection"], $query);
IS WRONG!
If you want a persistent connection, to avoid reconnecting on each DB query, read about MySQLi and Persistent connections : http://php.net/manual/en/mysqli.persistconns.php . If you are running on a PHP version under 5.3, I'd recommend using PDO (which I'd recommend regardless of the PHP version you're using).
I am curious is there a possibility in PHP to copy key/value from one memcached server directly to another using Memcached module?
Is connections to 2 different servers at one time allowed at all?
Thanks in advance!
The following would allow you to connect to two different Memcached servers and set the same data on both:
//Server A
$memcacheA = new Memcache;
$memcacheA->connect(216.239.51.99, 11211) or die ("Could not connect");
//Server B
$memcacheB = new Memcache;
$memcacheB->connect(115.239.51.98, 11211) or die ("Could not connect");
//Getting data from your database.
$myVal = $customObj->getSomethingFromDB();
//If data not stored on Server A
if($memcacheA->get('var_key') === false){
//Store it on Server A
$memcacheA->set('var_key', $myVar, MEMCACHE_COMPRESSED, 50);
}
//If data not stored on Server B
if($memcacheB->get('var_key') === false){
//Store it on Server B
$memcacheB->set('var_key', $myVar, MEMCACHE_COMPRESSED, 50);
}
Depending on your use case, this may or may not be a good solution. Depends on what your situation is and what you're attempting to achieve.
Just want to apologise in advance for writing so much text. Here is the problem: I use a persistent connection to connect to the database with a wait_timeout of 60 seconds and I store session data in a MySQL table. The problem I have is that the sessions just don't seem to use their own rows; each page refresh keeps starting a new session instead of using the old one. What is more, the persistent connections mentioned earlier keep starting new processes insead of using their own as they should. Since these two problems seem to have the same origin, I decided to put them here together. My PHP code is the following:
(View it on Pastebin)
mysql_pconnect('localhost', 'root') or die('Could not connect: ' . mysql_error());
mysql_set_charset('utf8');
mysql_select_db('azgoth') or die('Could not choose DB: ' . mysql_error());
session_set_cookie_params(3600,'/','www.azgoth',FALSE,TRUE);
session_set_save_handler('_open','_close','_read','_write','_destroy','_clean');
function _open(){
return true;}
function _close(){
return true;}
function _read($id){
$id = mysql_real_escape_string($id);
if ($result = mysql_query("SELECT data FROM sess_en WHERE id='$id'")) {
if (mysql_num_rows($result)) {
$record = mysql_fetch_assoc($result);
return $record['data'];}}
return '';}
function _write($id, $data){
$access = $_SERVER['REQUEST_TIME'];
$id = mysql_real_escape_string($id);
$access = mysql_real_escape_string($access);
$data = mysql_real_escape_string($data);
return mysql_query("REPLACE INTO sess_en VALUES('$id', '$access', '$data')");}
function _destroy($id){
$id = mysql_real_escape_string($id);
return mysql_query("DELETE FROM sess_en WHERE id='$id'");}
function _clean($max){
$old = $_SERVER['REQUEST_TIME'] - $max;
$old = mysql_real_escape_string($old);
return mysql_query("DELETE FROM sess_en WHERE access<'$old'");}
session_start();
Any ideas on what could be causing this issue?
EDIT: I thought at first that it was just in my head, but I can now confirm this: this weird thing keeps appearing randomly: it usually does, but not sometimes (rarely, in fact) doesn't..
The new session starting every time problem is probably because of the domain parameter you have passed to session_set_cookie_params(). You have passed www.azgoth, presumably because you have more than one top-level domain (TLD) and you want the cookies to be shared across all of them. This is not allowed. With what you have set, the TLD is azgoth, which is not (currently) possible, therefore the cookie will be invalid and will never be sent back to the server, ergo a new session will be started every time.
The persistent DB problem is probably server configuration related. The PHP manual states, on the page for mysql_pconnect():
Note, that these kind of links only work if you are using a module version of PHP. See the Persistent Database Connections section for more information.
...and...
Using persistent connections can require a bit of tuning of your Apache and MySQL configurations to ensure that you do not exceed the number of connections allowed by MySQL.
I have been writing php and mySQL functions all day and as I was writing the simplest part of my project I have hit a wall.
The function should simply count how many entries are in the database and return that number (If there is a more simple way please let me know, this is my first php + mysql project)
Here is the code:
function quoteCount(){
global $db;
$totalQuoteNum = array();
$query = "SELECT * FROM Quotes";
$result_set = mysqli_query($db, $query)
or die ("Query $query failed ".mysqli_error($db)); //fails here
$totalQuoteNum = mysql_num_rows($result_set)
or die ('couldnt count rows'.mysqli_error($db));
echo 'COUNTED EVERYTHING!!!';
return $totalQuoteNum;
};
Now when the die statement prints I get the string but not the mysqli error.
Things I have tried and ruled out:
$db is correct
query works in mysql
I wasnt sure if the database was connected, so I added the connect inside this function and stil nothing.
Any ideas? From what I see it should work and its not giving me any error to work from. Please help!
Based on the comments, it seems as though $db is the database name.
Functions such as mysqli_query() expect a database link (resource), not simply the database name.
This resource is created by constructing a new mysqli object. Following your procedural style, use mysqli_connect().
As part of a PHP web application, I'm querying a MySQL database using mysqli and prepared statements.
I've used exactly the same code on a few queries and it works, but on one particular query, it always returns an empty record set. I've run exactly the same query from the MySQL command line, and it correctly returns the result. I've checked the parameters being passed in, and they're fine.
I've spent the best part of a day trying to figure out why I'm always getting an empty record set with no errors or warnings. I've got PHP's errors set to display on the page, and I've got them set to E_ALL|E_STRICT. I still don't get any warnings or errors.
I've tried all the obvious things, like making sure I can actually connect to the database, checking the parameters that are being passed in, and making sure the row I'm trying to return actually exists in the database. I've had var_dump()s and die()s all over the page to check what's coming back, and it's always a legitimate, but empty, recordset.
function salt() {
return("I've removed my salt from this sample code");
}
function openDatabase() {
$conn = new mysqli("127.0.0.1", "username", "password", "database")
or die("Error: Could not connect to database.");
return($conn);
}
function checkUserCredentials($username, $password) {
$goodPassword = md5(salt().$username.$password);
$conn = openDatabase();
$query = $conn->stmt_init();
$query->prepare("SELECT id FROM users WHERE email = ? AND passwordHash = ?")
or die('Problem with query');
$query->bind_param("ss", $username, $goodPassword)
or die('Error binding parameters');
$query->execute() or die("Could not execute");
$query->bind_result($col1) or die ("Could not bind result");
if ($col1 !== 0) {
die("Authentication Complete");
} else {
die("Authentication Failure! Number of Rows: ".$query->num_rows." Username: " . $username . " Password Hash: " . $goodPassword);
}
}
Any feedback is appreciated. I'm sure I'm missing something simple, but if I didn't shave my head I'd be tearing my hair out right now.
Thanks
I'm not familiar with the mysqli library (I usually use PDO which provides a very similar cross platform API) so I can't immediately see any problem. However, you might try watching the mysqld log. See here for info:
http://dev.mysql.com/doc/refman/5.1/en/query-log.html
By tailing the log, you should be able to see the exact query that was submitted.
One final note, I notice you're using a fixed salt value. Wouldn't it be better to generate this value randomly each time you need it and then store it in the users table? Generally, a salt is not intended to be secret, it's just there to prevent people precomputing tables of passwords using the hash algorithm that you use.
In case anyone else runs into similar issues, it really helps if you run fetch() on your mysqli_stmt object.
In my code above, the solution looks like this:
$query->bind_result($col1) or die ("Could not bind result");
$query->fetch(); // <--- How could I forget to do this?
if ($col1 !== 0) {
return true;
} else {
return false;
}
Added on behalf of OP