I was just wondering how the PHP is behaving in the background.
Say I have a PHP which creates an array and populates it with names.
$names = Array("Anna", "Jackson" .... "Owen");
Then I have a input field which will send the value on every keypress to the PHP, to check for names containing the value.
Will the array be created on every call? I also sort the array before looping through it, so the output will be alphabetical. Will this take up time in the AJAX call?
If the answer is yes, is there some way to go around that, so the array is ready to be looped through on every call?
There's no difference between an AJAX request and a "normal" http request. So yes, a new php instance will be created for each request. If the time it takes to parse the script(s) is a problem you can use something like APC.
If those arrays are created at runtime and the time this takes is a problem you might store and share the values between requests in something like memcache
No matter what method you use to create the array, if it's in the code, if you pull it out of a database, a text file or any other source, when the web server gets an http request, ( whether it be Ajax or not ) it will start the execution of the PHP script, create its space in memory, and the array will be created.
There's only one entry point for a PHP script and it's the first line of it, when an http rquest points to it. (or when another script is included, which is the same)
As far as I know then it will have to create the array each time as the AJAX will make a new server request on each key press on the input input field. Each server request will create the array if you create the script to do so.
A better method would be to use a database to store the names.
Yes it will be created and destroyed every time you run the PHP script.
If this is a problem you could look at persisting this data somewhere (e.g. in a Session or in a Database), but I would ask whether it is really causing you so much of a performance problem that you need to do this?
(it's not a direct answer to your question, but it can help, if you are concerned about performances)
You say this :
Then I have a input field which will
send the value on every keypress to
the PHP
In this case, it is common pratice to not send the request to the server as soon as a key is pressed : you generally wait a couple of milliseconds (between 100 ms and 150 ms, I'd say), to see if there is not another keypress in that interval :
if the user types several keys, he usually types faster than the time you are waiting, so, you only send a request for the last keypress, and not every keypress
if the user types 4 letters, you only do 1 request, instead of 4 ; which is great for the health of your server :-)
speaking of time for the user : waiting 100 ms plus the time to go to the server, have the script running, and get back from the server is almost the same as without waiting 100 ms first ; so, not bad for the user
As a sidenote : if your liste of data is not too big (20 names is definitly OK ; 100 names would probably be OK ; 1000 might be too much), you could store it directly as a Javascript array, and not do an Ajax request : it's the fastest way (no client-server call), and it won't load your server at all.
Related
I'm building a PHP application which has a database containing approximately 140 URL's.
The goal is to download a copy of the contents of these web pages.
I've already written code which reads the URL's from my database then uses curl to grab a copy of the page. It then gets everything between <body> </body>, and writes it to a file. It also takes into account redirects, e.g. if I go to a URL and the response code is 302, it will follow the appropriate link. So far so good.
This all works ok for a number of URL's (maybe 20 or so) but then my script times out due to the max_execution_time being set to 30 seconds. I don't want to override or increase this, as I feel that's a poor solution.
I've thought of 2 work arounds but would like to know if these are a good/bad approach, or if there are better ways.
The first approach is to use a LIMIT on the database query such that it splits the task up into 20 rows at a time (i.e. run the script 7 separate times, if there were 140 rows). I understand from this approach it still needs to call the script, download.php, 7 separate times so would need to pass in the LIMIT figures.
The second is to have a script where I pass in the ID of each individual database record I want the URL for (e.g. download.php?id=2) and then do multiple Ajax requests to them (download.php?id=2, download.php?id=3, download.php?id=4 etc). Based on $_GET['id'] it could do a query to find the URL in the database etc. In theory I'd be doing 140 separate requests as it's a 1 request per URL set up.
I've read some other posts which have pointed to queueing systems, but these are beyond my knowledge. If this is the best way then is there a particular system which is worth taking a look at?
Any help would be appreciated.
Edit: There are 140 URL's at the moment, and this is likely to increase over time. So I'm looking for a solution that will scale without hitting any timeout limits.
I dont agree with your logic , if the script is running OK and it needs more time to finish, just give it more time it is not a poor solution.What you are suggesting makes things more complicated and will not scale well if your urls increase.
I would suggest moving your script to the command line where there is no time limit and not using the browser to execute it.
When you have an unknown list wich will take an unknown amount of time asynchronous calls are the way to go.
Split your script into a single page download (like you proposed, download.php?id=X).
From the "main" script get the list from the database, iterate over it and send an ajax call to the script for each one. As all the calls will be fired all at once, check for your bandwidth and CPU time. You could break it into "X active task" using the success callback.
You can either set the download.php file to return success data or to save it to a database with the id of the website and the result of the call. I recommend the later because you can then just leave the main script and grab the results at a later time.
You can't increase the time limit indefinitively and can't wait indefinitively time to complete the request, so you need a "fire and forget" and that's what asynchronous call does best.
As #apokryfos pointed out, depending on the timing of this sort of "backups" you could fit this into a task scheduler (like chron). If you call it "on demand", put it in a gui, if you call it "every x time" put a chron task pointing the main script, it will do the same.
What you are describing sounds like a job for the console. The browser is for the users to see, but your task is something that the programmer will run, so use the console. Or schedule the file to run with a cron-job or anything similar that is handled by the developer.
Execute all the requests simultaneously using stream_socket_client(). Save all the socket IDs in an array
Then loop through the array of IDs with stream_select() to read the responses.
It's almost like multi-tasking within PHP.
I'm using PHP as my scripting language and mySQL as my database.
Im wondering if saving into database on form submit is better than saving on every keypress.
Which is better in terms of usability/ux and in performance?
Saving on every keypress means:
You'll need a server capable of handling more requests
You'll need smarter logic then every key press as most people can press keys faster than most connections can round trip an HTTP request. Possibly something like "Every 30 seconds, but only if the data has been changed, but delayed until a response is received for the last request (or it times out)".
Saving on keypress is definitely a very bad idea ! A typical form with 10 fields, will require at least 100 calls to the database. Not very optimal. Even from a UX point of view; But you can create a setTimeout for saving the user input, say, every 30sec (the setTimeout will be initialized after the first field has been changed, for example).
I need to check for updates on a (max) one second interval for updates.
I'm now looking for the fastest way to do that using AJAX for the requests and PHP and MySQL.
Solution 1
Every time new data, that needs to be retreived by other clients, is added to the MySQL database a file.txt is updated with 1. AJAX makes a request to a PHP file which will check if file.txt contains a 1 or 0. If it contains a 1 it will get the data from the MySQL database and return it to the client.
Solution 2
Every AJAX request calls a PHP file which will check directly into MySQL database for new data.
Solution ..?
If there is any faster solution i'd be happy to know! (considering I can only use PHP/MySQL and AJAX)
Avoiding the database will probably not make the process significantly faster, if at all.
You can use a comet-style ajax request to get near real-time polling. Basically, create an ajax request as usual to a php-script, but on the server side you poll the database and sleep for a short interval if there is nothing new. Repeat until there is something of interest for the client. If nothing appears within a timeframe of e.g. 60 seconds, close the connection down. On the client side, you only open a new connection once the first has terminated (either with a response or as a timeout).
See: https://en.wikipedia.org/wiki/Comet_(programming)
Our company deals with sales. We receive orders and our PHP application allows our CSRs to process these orders.
There is a record in the database that is constantly changing depending on which order is currently being processed by a specific CSR - there is one of these fields for every CSR.
Currently, a completely separate page polls the database every second using an xmlhhtp request and receives the response. If the response is not blank (only when the value has changed on the database) it performs an action.
As you can imagine, this amounts to one databse query per second as well as a http request every second.
My question is, is there a better way to do this? Possibly a listener using sockets? Something that would ping my script when a change has been performed without forcing me to poll the database and/or send an http request.
Thanks in advance
First off, 1 query/second, and 1 request/second really isn't much. Especially since this number wont change as you get more CSRs or sales. If you were executing 1 query/order/second or something you might have to worry, but as it stands, if it works well I probably wouldn't change it. It may be worth running some metrics on the query to ensure that it runs quickly, selecting on an indexed column and the like. Most databases offer a way to check how a query is executing, like the EXPLAIN syntax in MySQL.
That said, there are a few options.
Use database triggers to either perform the required updates when an edit is made, or to call an external script. Some reference materials for MySQL: http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
Have whatever software the CSRs are using call a second script directly when making an update.
Reduce polling frequency.
You could use an asynchronous architecture based on a message queue. When a CSR starts to handle an order, and the record in the database is changed, a message is added to the queue. Your script can either block on requests for the latest queue item or you could implement a queue that will automatically notify your script on the addition of messages.
Unless you have millions of these events happening simultaneously, this kind of setup will cause the action to be executed within milliseconds of the event occuring, and you won't be constantly making useless polling requests to your database.
I have a basic HTML file, using jQuery's ajax, that is connecting to my polling.php script every 2 seconds.
The polling.php simply connections to mysql, checks for ID's newer than my hidden, stored current ID, and then echo's if there is anything new. Since the javascript is connecting every 2 seconds, I am getting thousands of connections in TIME_WAIT, just for my client. This is because my script is re-connecting to MySQL over and over again. I have tried mysql_pconnect but it didn't help any.
Is there any way I can get PHP to open 1 connection, and continue to query using it? Instead of reconnecting every single time and making all these TIME_WAIT connections. Unsure what to do here to make this work properly.
I actually ended up doing basic Long Polling. I made a simple PHP script to to an infinite while loop, and it queries every 2 seconds. If it finds something new, it echoes it out, and breaks the loop. My jquery simply ajax connects to it, and waits for a reponse; on reponse, it updates my page, and restarts the polling. Very simple!
PS, the Long Polling method also reduces browser memory issues, as well as drastically reduces the TIME_WAIT connections on the server.
There's no trivial way of doing this, as pconnect doesn't work across multiple web page calls. However, some approaches to minimise the database throughput would be:
Lower the polling time. (2 seconds is perhaps a bit excessive?)
Have a "master" PHP script that runs every 'n' seconds, extracts the data from the database and saves it in the appropriate format (serialised PHP array, XML, HTML data, etc.) in the filesystem. (I'd recommend writing to a temp file and then renaming over the existing one to minimise any partial file collection issues.) The Ajax requested PHP page would then simply use the information in this data file.
In terms of executing the master PHP script, you could either use cron or simply let the user who first requests the page when the contents of file is deemed too stale. (You could use the data file's timestamp for this purpose via the filemtime function.) I'd personally use the latter approach, as cron is overkill for this purpose.
You could take this even further and use memcached instead of a flat file, etc. if so required. (That said, it would perhaps be an over-complex solution at this stage of affairs.)