I have been trying to serialize phpseclib connection since I am loading some php pages from ajax and I dont want to reconnect again and again.
Page 1 - define SSH2 First
require("Net/SSH2.php");
session_start();
$ssh = new Net_SSH2 ("localhost");
if ($ssh->login($username, $pass)) {
$_SESSION['obj'] = serialize($ssh);
}else{
echo "Invalid Login !!!";
}
Page 2 - Get Stored session with unserialize
session_start();
require("Net/SSH2.php");
$ssh = unserialize($_SESSION['obj']);
echo $ssh->exec('ls');
I want to put Login information in $_SESSION['obj'] too so Whenever I am on that php page i just $ssh = unserialize($_SESSION['obj']); and then $ssh->exec('pwd') ..
Is there work around or will I have to always connect/login to Net/SSH2.php whenever I am on that PHP page ???
Depending on which PHP version you have, you could try to declare a static variable for the ssh connection.
If phpseclib uses pfsockopen it might be able to reuse existing connections - but that is a longshot, and might require modification of the library.
But generally speaking you cannot do what you want in PHP. When the script is finished all open sockets are closed, as the executing process terminates.
You certainly can't store it in a session variable - as soon as the Net_SSH2 object goes out of scope it is destroyed.
The only way to have a persistent connection is to actually have a script constantly running which is keeping the connection open. Which means you have one script with a never ending while (true) { ... } loop which opens a connection once and keeps it. You then need to find a way to communicate with this script to make it execute commands. AMQP, ØMQ, Gearman, sockets and similar techniques can be employed for that.
Related
I am using Symfony's Custom Session handler. It works fine when I set the session for the first time but when I refresh the page. The page will keep on loading and after 30 seconds which is max_execution_time defined in php.ini, the errors are shown. To setup custom save handler, I created a table sessions in ratchet database. The structure and the data in the table:
Now the script, on the top of page looks like this to initialize custom save handler:
<?php
ini_set('session.auto_start', false);
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
require dirname(__DIR__) . '/vendor/autoload.php';
$pdo = new \PDO('mysql:host=localhost;dbname=ratchet', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$storage = new NativeSessionStorage(array(), new PdoSessionHandler($pdo)); // Here when PdoSessionHandler class is initialized again on refreshing it locks the page there
$session = new Session($storage);
$session->start();
$username = $session->get('username');
The errors thrown by PHP script for Line 153:
Line 153 is a statement in the following method which executes and reads a session value from database.
private function doRead($sessionId)
{
$this->sessionExpired = false;
if (self::LOCK_ADVISORY === $this->lockMode) {
$this->unlockStatements[] = $this->doAdvisoryLock($sessionId);
}
$selectSql = $this->getSelectSql();
$selectStmt = $this->pdo->prepare($selectSql);
$selectStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
$selectStmt->execute(); // Line 153
Is something broken in the framework's component or am I missing something? I have followed the documentation. I can't find anything that is new or has been added by myself.
Addition
In addition to initializing session in the web app, I initialize symfony session in my server script as well because it is required in order to attach the same session object to each connection. The points to be noted:
The application works fine for the first attempt.
Chat server works as intended. It never throws an error.
When the page in which I connect to the websocket server is refreshed, it remains in the loading state for 30 seconds. Then the errors occur.
Same happens in other browsers. Like it will let the connection establish but when I will refresh ........ See above :D
You mentioned that:
I initialize symfony session in my server script as well
Does this also call new NativeSessionStorage?
What I think is happening is that you are creating essentially two session handlers but PHP only knows about one and thus only closes the database connection / lifts the database lock for one of them. Let me see if I can explain clearly. Every time you instantiate NativeSessionStorage the class registers the sessionHandler (the pdo session handler in your case) with php via session_set_save_handler which you can see in the NativeSessionStorage code here.
When PHP stops execution it calls the PdoSessionHandler->close() method. However since you have two instances and php only has one registered as the session handler, its closing one but not the other. Which keeps the database locked. Based on your description I think this may be your problem. You should be able to easily test this by explicitly calling Session->save() try doing this explicitly in your app and server code to see if you don't get the locked error anymore.
Hope this helps!
Is the session closing when the websocket disconnects? If not, it is keeping the lock on the session record and not allowing the incoming request to continue past starting the session. The initial page load works because the websocket picks up the session when the page load is complete.
I have a normal website. It uses PHP to call a MySQL table. To save on typing it out all the time, I include() a connect.php file which connects to the database for me on every page. The website keeps getting a "mysql too many connections" error. Is it a bad idea to connect at the start of a page like this?
Should I create a new connection each time a PHP script needs it, then close that connection with mysql_close after that script is done? I had avoided doing as it would add repeated lines of code to the website but I'm wondering if that's what's causing the issue?
So at the moment my code is similar to this:
<?php
include("connect.php"); //connects to database using mysql_connect() function
...
PHP script that calls mysql
...
another PHP script that calls mysql
?>
Should I change it to something like this?
<?php
mysql_connect('host', 'username', 'password');
mysql_select_db('db');
PHP code that calls mysql
mysql_close();
...
mysql_connect('host', 'username', 'password');
mysql_select_db('db');
more PHP code that calls mysql
mysql_close();
?>
You should avoid making new connections to your database, as long as possible.
Making connection to database is a slow and expensive process. Having an opened connection consume few resources.
By the way, stop using mysql_* functions. Use mysqli_* or PDO.
Should I create a new connection each time a PHP script needs it [...] ?
Yes, that makes most sense, especially if not every page needs a mysql connection.
In PHP this works by setting up the database credentials in the php.ini file and you can just call mysql_select_db and it will automatically connect to the configured database if no connection exists so far.
If you write new code, encapsulate the database connection in an object of it's own so that you can more fine-grained control when to connect to the database.
Modern frameworks like for example Silex allow you to lazy load such central components (Services), so you have configured them and can make use of them when you need them but you don't need to worry about the resources (like the connection limit in your example).
[...] close that connection with mysql_close after that script is done?
You don't need that normally because PHP does this for you.
I do not think there is anything really wrong with this style of coding. It all depends on what kind of app you are writing. Just make sure you check your scripts well and get ride of any errors, you should be fine.
This is what i usually do
<?php session_start(); include "inc/config.php";
//require_once('chartz/lib/idiorm.php');
if ($_SESSION["login1"]== "Superadmin" or $_SESSION["login1"]== "User" or $_SESSION["login1"]=="Administrator")
{
$snames = $_SESSION["name1"];
$id = $_SESSION["id1"];
$stype = $_SESSION["login1"];
$stokperm = $_SESSION['stokperm'];
$navtype = $_GET['nav'];
include("inc/ps_pagination.php");
}
else
{
header ("location: ../../../index.php");
}
?>
Am not saying its the very best way out there, we are all still learnig...
I also thing you should take the advice of blue112 very seriously. Most of my apps are writing in the old fashion way, but Use mysqli_* or PDO is the way to go.
I have a JavaScript functions which calls a PHP function through AJAX.
The PHP function has a set_time_limit(0) for its purposes.
Is there any way to stop that function when I want, for example with an HTML button event?
I want to explain better the situation:
I have a php file which uses a stream_copy_to_stream($src, $dest) php function to retrieve a stream in my local network. The function has to work until I want: I can stop it at the end of the stream or when I want. So I can use a button to start and a button to stop. The problem is the new instance created by the ajax call, in fact I can't work on it because it is not the function that is recording but it is another instance. I tried MireSVK's suggest but it doesn't worked!
Depending on the function. If it is a while loop checking for certain condition every time, then you could add a condition that is modifiable from outside the script (e.g. make it check for a file, and create / delete that file as required)
It looks like a bad idea, however. Why you want to do it?
var running = true;
function doSomething(){
//do something........
}
setInterval(function(){if(running){doSomething()}},2000); ///this runs do something every 2 seconds
on button click simply set running = false;
Your code looks like:
set_time_limit(0);
while(true==true){//infinite loop
doSomething(); //your code
}
Let's upgrade it
set_time_limit(0);
session_start();
$_SESSION['do_a_loop'] = true;
function should_i_stop_loop(){
#session_start();
if( $_SESSION['do_a_loop'] == false ) {
//let's stop a loop
exit();
}
session_write_close();
}
while(true==true){
doSomething();
should_i_stop_loop(); //your new function
}
Create new file stopit.php
session_start();
$_SESSION['do_a_loop'] = false;
All you have to do now is create a request on stopit.php file (with ajax or something)
Edit code according to your needs, this is point. One of many solutions.
Sorry for my English
Sadly this isn't possible (sort of).
Each time you make an AJAX call to a PHP script the script spawns a new instance of itself. Thus anything you send to it will be sent to a new operation, not the operation you had previously started.
There are a number of workarounds.
Use readystate 3 in AJAX to create a non closing connection to the PHP script, however that isn't supported cross browser and probably won't work in IE (not sure about IE 10).
Look into socket programming in PHP, which allows you to create a script with one instance that you can connect to multiple times.
Have PHP check a third party. I.E have one script running in a loop checking a file or a database, then connect to another script to modify that file or database. The original script can be remotely controlled by what you write to the file/database.
Try another programming language (this is a silly option, but I'm a fan of node). Node.js does this sort of thing very very easily.
I am creating a simple Web Application in PHP for my college project. I am using the MySQL database.
I connect to the database in login.php. After connection I assign the connection to $_SESSION["conn"] and then redirect to main.php.
In main.php I write $conn = $_SESSION["conn"]. But the connection in $conn does not work.
I thought that as the login.php script ends, the connection gets closed. So I tried using mysql_pconnect instead of mysql_connect but that too does not work.
I know I can reconnect to the database in every PHP file. But I don't want to do this. I want to use the same connection in all PHP files.
Instead of saving the DB connection in a session you should make the connection calls in a separate file such as db.php and then require it from each of your scripts. For example, place your connection in db.php:
mysql_connect('...', '...', '...');
mysql_select_db('...');
and then bring it in in login.php:
require('db.php');
$res = mysql_query('...');
You can then do the same for each PHP file that needs access to the DB and you'll only ever have to change your DB access credentials in one file.
After connection I assign the connection to $_SESSION["conn"] and then redirect to main.php.
You'll probably want to read up on PHP sessions. You can't store resources (database connections, file handles, etc) in a session, because they can not be serialized and stored.
Keep in mind that each and every visit to a PHP script invokes a new instance of the PHP interpreter (via CGI, via FastCGI, or via a built-in module), and invokes a new instance of the script. Nothing is shared between script calls, because the entire environment goes away when the script exits.
The other answers are correct -- you'll need to connect to the database on every script call. Place the connection in a common include file for convenience.
The second request may not be served by the same web server process as the first, which means that you will have a completely separate set of database resources. You'll need to connect again in this new process in order to run queries.
What I normally have is a Connection class that pages will require in order to establish a connection. Something along the lines of:
class Connection {
public $dbConnection = null;
public $isConnectionActive = false;
private $dbServer = null;
private $dbCatalog = null;
private $dbUser = null;
private $dbPassword = null;
}
This class handles opening and closing of the connection on any pages.
It sounds that you want to make your php connections persistants , in that way and if it is so , then you have to create a PDO Object with the required parameters to create a new PHP PDO Object that will attempt to connect to mysql , and in the object instanciation , try to pass persistancy option value to true , you may have available in every php scripts the same PDO Connection Objetc but you will end up to face issues with that way ... but it is not reconmmanded as PHP Programming Best Pratices ... the best way to do so is to include a connection file for every script in your project. Read PHP Documentation for Persistant Connections in order to learn more about Issues found for these Connection Objets especially for recent php versions. PHP Announced that Persistant Connections are on the way to be dropped from futur version as it may increase server workload with persistant ressources ... Sorry if it is too late
How can you have only one declaration of the database connection variable, $dbconn?
My login script is based on the following procedure
If the user is not authenticated, he is thrown back to the login page
If the user is authenticated, he gets an $_SESSION["logged_in"] = true;
Then when the user is browsing the main page or other pages that need auth, they just check if the $_SESSION["auth"] is set.
I have the database variable only at the beginning of my index.php:
$dbconn = pg_connect("host=localhost port=5432 dbname=masi user=masi password=123");
I do not the connection by db_close() anywhere in my codes.
I source my login script to index.php which uses my database.
However, I get the standard warnings of not getting access to db when I do not have the variable declaration also in my scripts. If I add the declaration to each of my scripts, I get an access to db.
We need to first understand how PHP is running the show here before we can delve into the wide, wide world of database connections.
Each PHP page request fires off a new PHP script. While you may have sessions turned on, that's an internal PHP construct only. The database sees this as a new connection/process connecting to the server. Therefore, it creates a new process on the database for it, so long as you call your pg_connect code. Otherwise, Postgres has no idea who you are or what session you want to use. Moreover, once the parent process dies, it generally kills the Postgres session (in this case, the PHP script runs and then dies once it's finished). Sometimes these can leave zombies roaming the streets of Postgres, but by and large, it'll just kill them.
If you want to use SQL code in your PHP script, you must connect to the database in that script before making a call to Postgres.
If i remember your other question you're redirecting to login.php? Which means that no the dbconn variable will not exist because it was initialised on another page.
if you required login.php from index.php it would work
$dbconn = pg_connect("host=localhost port=5432 dbname=masi user=masi password=123");
require_once('login.php');