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.
Related
i try to create a little login+survey and try to write all data to a database. Especially it is important, to get a session id for each user in order to add information of each page of the survey to the right line of the database.
My problem is here, that it seems that the session is either not started or i can not create a session id. Writing in the database already works, but not if i include the lines about the session.
After google'ing a lot that always took me to the same answer (which is not working for me) i try it here. Here is my code, first the callDatabase.php is called, in this file a session id is created and the database entry is made (idk if this is the best solution though, i guess not xD):
<script type="text/javascript">
$.post( 'callDatabase.php', { 'entry[]': ["init"]} );
</script>
callDatabase.php:
<?php
header('Content-Type: text/json');
$test = $_POST['entry'];
session_start();
$sID = session_id();
$timestamp = time();
$servername = "local";
$username = "root";
$password = "rootpw";
$conn = new mysqli($servername, $username, $password);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
mysqli_select_db($conn, 'myDb');
$sql = "INSERT INTO myTable (sID, timestamp, t1, rating, start, end, color, fight, completed)
VALUES ('$sID', '$timestamp', '-', '4', '_', '_', '_', '_', 'false')";
mysqli_query($conn, $sql);
mysqli_close($conn);
session_unset();
session_destroy();
$_SESSION = array();
?>
Like i said, without the session stuff, it is working fine, with it, the browser is running forever and i get no entry in my database. Since i get no error message i did not find any solution about how to fix it.
It is running locally, with XAMPP and a mysql database.
Problem is caused by Xampp, since some ports might be blocked, code is working with virtual machine, linux and apache server together with phpmyadmin for example. Checking the errorlogs will help to find out if the blocked ports are causing the problem.
To solve the problem together with xampp, it is recommended to deactivate all tools that might block the needed ports (skype, connection via vpn, antivirus tool, ...) or change the ports to have no conflicts there.
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 trying to send two values to my server to be input into a database in the same row, the problem I have is that it isn't possible to send both values in one request. So what I want to do is send both the values in separate requests but handle them on the server at once so I can add the values into a database as one entry. My php isn't very strong, and I have no idea how to go about doing this. Is it possible? How would I do it?
Here's what I have so far:
<?php
$user = "user";
$pass = "pass";
$table = "database";
if(isset($_POST['currentUser']))
{
$userID = 'currentUser';
}
if(isset($_POST ['e.regid']))
{
$regid = 'e.regid';
}
if ($regid && $userID != null)
{
$con = mysqli_connect("localhost", $user, $pass);
mysqli_select_db($con, $table);
if (mysqli_connect_errno$con))
{
echo "Error connecting to the DB: " . mysqli_connect_errno());
}
else
{
"INSERT INTO gek_devices('regid', 'pin') VALUES ($regid, $userID)";
}
}
No, due to network latency and unreliability there's not even any guarantee that both requests will ever arrive at the server, let alone within a minute apart, let alone that you could run code once handling both requests. In practice chances are over 90% that both requests will not even be handled by the same Apache process on the server, given that a default Apache install on *nix will prefork 10 'spare' instances.
If you need to process the data 'simultaneously` you need to send them in the same request, that's the only way to guarantee atomicity.
Your intended solution is completely impossible, but also a glaring XY problem. Solve why you can't send the values simultaneously right now instead of focusing on hacky workarounds following that.
I have a page where few thousands of users can hit a method at the same time . I do have following code where I connect every time . Since this will go to a seperate memcache server will this cause slowdowns is there a way to connect just once and reuse that connection ? Do I have to close connection after every request ?
$primary_connected = $memcache_primary->connect($primary_memcache_server, 11211);
if($primary_connected){
$data = $memcache_primary->get($key);
if ($data != NULL) {
return data;
}
}
else{
/////Get data from database
}
If you are using the PHP memcached class (the one with the d on the end, not memcache) then yes, you can open a persistent connection.
You can pass a persistent ID to the constructor which will open a persistent connection and subsequent instances that use the same persistent ID will use that connection.
$memcached = new Memcached('method_name_or_persistent_identifier');
$memcached->addServer(...);
// use it
Hope that helps.
See Memcached::__construct() for more details.
I am setting up a EC2 cluster with a load balancer. I have seperate DB server which has mysql running on it. I have 3 webservers running, mostly for high availability, and of course its round-robin load balancing it seems, so every page you go to you get a different server which looses your session.
I am trying to setup PHP to store it in the DB. I have setup a table, and setup all the functions (open,close,etc). and I have set:
session_set_save_handler('_open',
'_close',
'_read',
'_write',
'_destroy',
'_clean');
But when I login or anything on the site I check the table and nothing has been written. I am not sure If i need to change something in the php.ini file. If so what is the value to change?
Thanks!!
EDIT: functions:
function _open(){
global $con;
connect();
}
function _close(){
global $con;
//mysql_close();
}
function _read($id){
global $con;
$id = mysql_real_escape_string($id);
$sql = "SELECT data FROM sessions WHERE id = '$id'";
if ($result = mysql_query($sql, $con)) {
if (mysql_num_rows($result)) {
$record = mysql_fetch_assoc($result);
return $record['data'];
}
}
return '';
}
function _write($id, $data)
{
global $con;
$access = time();
$id = mysql_real_escape_string($id);
$access = mysql_real_escape_string($access);
$data = mysql_real_escape_string($data);
$sql = "REPLACE
INTO sessions
VALUES ('$id', '$access', '$data')";
return mysql_query($sql, $con);
}
function _destroy($id)
{
global $con;
$id = mysql_real_escape_string($id);
$sql = "DELETE
FROM sessions
WHERE id = '$id'";
return mysql_query($sql, $con);
}
function _clean($max)
{
global $con;
$old = time() - $max;
$old = mysql_real_escape_string($old);
$sql = "DELETE
FROM sessions
WHERE access < '$old'";
return mysql_query($sql, $con);
}
session_set_save_handler('_open',
'_close',
'_read',
'_write',
'_destroy',
'_clean');
The function you're using will interrupt the normal session function and insert your code in to act, then carry on with other internal functions.
In the functions where you aren't really doing anything session-wise (things like '_open' and '_close'), you need return something to carry on the command or it will just die right there.
Example:
function _open($save_path, $session_name){
global $con;
connect();
return true; //Do nothing but carry on
}
function _close(){
global $con;
//mysql_close();
return true; //Do nothing but carry on
}
Really this is not the answer to your question, but if you need really high availability I can suggest that storing sessions in mysql is not a good method.
A better practice: Put your sessions in memcache. Memcache server it's easy to install. Memcache client is easy to install and php support storing session in memcache without programming!!! Memcache store data in memory, not in disk and it's faster.
Here you can view a good post about this: http://kevin.vanzonneveld.net/techblog/article/enhance_php_session_management/
Luck!!
How come you can't use cookies? and just have the script check if the cookies is present then read the value's from there. Unless security is an issue .. I suggest cookies over sessions for cheap scalability ..Writing session's in the database won't be good and will probably result in expensive queries being ran for no reason.
The best database for sessions is going to be something like Redis or MonogDB and not MySQL and not memcached. You could use memcached depending on how much traffic you get, but Redis or MongoDB is a much more scalable database. Also, since you're on EC2, you may want to look at Amazon SimpleDB. It's a key/value store so it should lend itself well to sessions.
I'd personally run with MongoDB because not only can you store your sessions there, but you can take what you do have from MySQL and cache it there too as well as store other data in Mongo...Or just think about converting your site's database altogether because you'll probably fall in love with MongoDB =)
You can also look into the settings of HAProxy under Application Cookies. That may help you too.