Let's see if I make myself clear. I have an old set of scripts that run well on PHP4 and better don't thouch em. I have to integrate a new functionality implemented on PHP5, I need just to invoke a script on the new app from the old one.
To not have to touch the old stuff I think to somehow "kin of remotely" invoke the new one, need only to pass the $_REQUEST[] data. I can not include it as that would require migrating to another PHP version (and some name clashing). I don't need any output from the new one.
What would be the cleaner way to "call" that script passing parameters, fopen("http://theserver.com/thescript.php"....) and then passing all the necessary headers to pass the parameters? or there's somethign more direct?
Thanks!
If you need to pass POST data, you can use cURL; otherwise, you can just do file_get_contents('http://example.com/yourscript.php?param1=x¶m2=y¶m3=...'); and the HTTP wrapper will do the request for you (simplest way).
You're going to give yourself nightmares with this.
But if you really need to do it, you're not going to be able to rely on fopen. I would recommend using cURL, as Piskvor suggests.
But please, make sure you're validating and escaping any data you're pushing across correctly, or you're in for a world of hurt - the fact that you're making a cURL request to the other part of the system means that in theory, anyone else can do exactly the same thing.
This is most definitely not a long term solution, I would advise you rewrite the old parts as a priority.
After considering what you suggested on previous answers and considering safety I thought something: If both scripts are on the same server the "called" one should be on the same IP than the caller so if ips differ the invoked should not run. Is that a good idea?
Related
Okay, so I'm relatively naive in my knowledge of the PHP VM and I've been wondering about something lately. In particular, what the request lifecycle looks like in PHP for a web application. I found an article here that gives a good explanation, but I feel that there has to be more to the story.
From what the article explains, the script is parsed and executed each time a request is made to the server! This just seems crazy to me!
I'm trying to learn PHP by writing a little micro-framework that takes advantage of many PHP 5.3/5.4 features. As such, I got to thinking about what static means and how long a static class-variable actually lives. I was hoping that my application could have a setup phase which was able to cache its results into a class with static properties. However, if the entire script is parsed and executed on each request, I fail to see how I can avoid running the application initialization steps for every request servered!
I just really hope that I am missing something important here... Any insight is greatly apreciated!
From what the article explains, the script is parsed and executed each time a request is made to the server! This just seems crazy to me!
No, that article is accurate. There are various ways of caching the results of the parsing/compilation, but the script is executed in its entirety each time. No instances of classes or static variables are retained across requests. In essence, each request gets a fresh, never-before execute copy of your application.
I fail to see how I can avoid running the application initialization steps for every request servered!
You can't, nor should you. You need to initialize your app to some blank state for each and every request. You could serialize a bunch of data into $_SESSION which is persisted across requests, but you shouldn't, until you find there is an actual need to do so.
I just really hope that I am missing something important here...
You seem to be worried over nothing. Every PHP site in the world works this way by default, and the vast, vast majority never need to worry about performance problems.
No, you are not missing anything. If you need to keep some application state, you must do it using DB, files, Memcache etc.
As this can sound crazy if you're not used to it, it's sometimes good for scaling and other things - you keep your state in some other services, so you can easily run few instances of PHP server.
A static variable, like any other PHP variable only persists for the life of the script execution and as such does not 'live' anywhere. Persistence between script executions is handled via session handlers.
I am trying to trace the flow of execution in some legacy code. We have a report being accessed with
http://site.com/?nq=showreport&action=view
This is the puzzle:
in index.php there is no $_GET['nq'] or $_GET['action'] (and no
$_REQUEST either),
index.php, or any sources it includes, do not include showreport.php,
in .htaccess there is no url-rewriting
yet, showreport.php gets executed.
I have access to cPanel (but no apache config file) on the server and this is live code I cannot take any liberty with.
What could be making this happen? Where should I look?
Update
Funny thing - sent the client a link to this question in a status update to keep him in the loop; minutes latter all access was revoked and client informed me that the project is cancelled. I believe I have taken enough care not to leave any traces to where the code actually is ...
I am relieved this has been taken off me now, but I am also itching to know what it was!
Thank you everybody for your time and help.
There are "a hundreds" ways to parse a URL - in various layers (system, httpd server, CGI script). So it's not possible to answer your question specifically with the information you have got provided.
You leave a quite distinct hint "legacy code". I assume what you mean is, you don't want to fully read the code, understand it even that much to locate the piece of the application in question that is parsing that parameter.
It would be good however if you leave some hints "how legacy" that code is: Age, PHP version targeted etc. This can help.
It was not always that $_GET was used to access these values (same is true for $_REQUEST, they are cousins).
Let's take a look in the PHP 3 manual Mirror:
HTTP_GET_VARS
An associative array of variables passed to the current script via the HTTP GET method.
Is the script making use of this array probably? That's just a guess, this was a valid method to access these parameter for quite some time.
Anyway, this must not be what you search for. There was this often misunderstood and mis-used (literally abused) feature called register globals PHP Manual in PHP. So you might just be searching for $nq.
Next to that, there's always the request uri and apache / environment / cgi variables. See the link to the PHP 3 manual above it lists many of those. Compare this with the current manual to get a broad understanding.
In any case, you might have grep or a multi file search available (Eclipse has a nice build in one if you need to inspect legacy code inside some IDE).
So in the end of the day you might just look for a string like nq, 'nq', "nq" or $nq. Then check what this search brings up. String based search is a good entry into a codebase you don't know at all.
I’d install xdebug and use its function trace to look piece by piece what it is doing.
EDIT:
Okay, just an idea, but... Maybe your application is some kind of include hell like application I’m sometimes forced to mess at work? One file includes another, it includes another and that includes original file again... So maybe your index file includes some file that eventually causes this file to get included?
Another EDIT:
Or, sometimes application devs didn’t know what is a $_GET variable and parsed the urls themselves -> doing manual includes based to based urls.
I don't know how it works, but I know that Wordpress/Silverstipe is using is own url-rewriting to parse url to find posts/tags/etc. So the url parsing maybe done in a PHP script.
Check your config files (php.ini and .htaccess), you may have auto_prepend_file set.
check your crontab, [sorry I don't know where you would find it in cpanel]
- does the script fire at a specific time or can you see it definitely fires only when you request a specific page?
-sean
EDIT:
If crontab is out, take a look at index.php [and it's includes] and look for code that either loops over the url parameters without specifically noting "nq" and anything that might be parsing the query string [probably something like: $_SERVER['QUERY_STRING'] ]
-sean
You should give debug_backtrace() (or debug_print_backtrace() a try. The output is similar to the output of an Exception-stacktrace, thus it should help you to find out, what is called when and from where. If you don't have the possibility to run the application on a local development system, make sure, that nobody else can see the output
Are you sure that you are looking at the right config or server? If you go the url above you get an error page that seems to indicate that the server is actually a microsoft iis server and not an apache one.
I have a rather big php site, which was written for php4 and register_globals enabled. It is old custom CMS. Now I want to run it on the php5 hosting without register_globals. Is it possible to change parameters parsing from $id to $_GET["id"] automatically, with some script?
I can get parameters names from wget -r on this site.
It have dozens of php scripts, and it is not very easy to do this change manually.
PS: UPDATE: I want to convert only GET variables. The additional line is $var_name = $_GET["var_name"] for each parameter. This line should be inserted very high in the script, e.g. by adding a new <? ?> section at very top.
Running such tool would introduce great risk of introducing errors in code.
I'd suggest running extract() on superglobals, so that you force register_globals and aplication will work properly.
http://php.net/manual/pl/function.extract.php
Next, when everything will be ok, write an OO wrapper for input parameters, pack it into nice DI Container and start manually transitioning whole script to the new style.
I don't know of any tools that help you in the conversion, but you have several options:
Simulate register globals by doing the same thing that register_globals did: At the beginning of the script, put all variables from GET and POST into the global variable namespace (i.e. via extract). While this is fastest and the most easy solution, it will lead to the security problems that register_globals was known for, and it doesn't help with the performance of your application
Determine the variables that are used and load them only via the init script into $GLOBALS only. Still not nice
Determine the variables that are used and replace the GLOBALS usage with REQUEST
Walk through it manually. This way, you can be sure everything is correct and will have the least trouble afterwards.
From your description, solution 1 or 2 might be the best for you since the cms doesn't seem to be updated anyway (which is a shame).
Although the actual finding/replacing might take more time, doing this manually will most likely result in less bugs / weird behaviour.
If are not the original author of the application, then this manual finding/replacing is also an opportunity for you to become much more familiar with the codebase than some automatic method.
Automatic: fast, almost definitely will result in some horrible bugs
Manual: slower (likely), almost definitely will result in better understanding, less bugs - and any bugs that are introduced will be easier to fix because of your better understanding.
I'm using curl_multi functions to request multiple URLs and process them as they complete. As one connection completes all I really have is the cURL handle (and associated data) from curl_multi_info_read().
The URLs come from a job queue, and once processed I need to remove the job from the queue. I don't want to rely on the URL to identify the job (there shouldn't be duplicate URLs, but what if there is).
The solution I've worked up so far is to use the cURL handle as an array key pointing to the jobid. Form what I can tell, when treated as a string the handle is something like:
"Resource id #1"
That seams reasonably unique to me. The basic code is:
$ch = curl_init($job->getUrl());
$handles[$ch] = $job;
//then later
$done = curl_multi_info_read($master);
$handles[$done['handle']]->delete();
curl_multi_remove_handle($master, $done['handle']);
Is the cURL handle safe to use in this way?
Or is there a better way to map the cURL handles to the job that created them?
Store private data inside the cURL easy handle, e.g. some job ID:
curl_setopt($ch, CURLOPT_PRIVATE, $job->getId());
// then later
$id = curl_getinfo($done['handle'], CURLINFO_PRIVATE);
This "private data" feature is not (yet) documented in the PHP manual. It was introduced already in PHP 5.2.4. It allows you to store and retrieve a string of your choice inside the cURL handle. Use it for a key that uniquely identifies the job.
Edit: Feature is now documented in the PHP manual (search for CURLOPT_PRIVATE within the page).
It will probably work thanks to some implicit type cast, but it doesn't feel right to me at all. I think it's begging for trouble somewhere down the line, with future versions that treat resources differently, different platforms...
I personally wouldn't do it, but use numeric indexes.
I have to agree with Pekka... it will probably work but it smells bad. id use straight up integers as Pekka suggests or wrap the handles in a simple class and then use spl_object_hash or have the constructor generate a uniqid when its set up.
I'm trying to write a page that calls PHP that's stored in a MySQL database. The page that is stored in the MySQL database contains PHP (and HTML) code which I want to run on page load.
How could I go about doing this?
You can use the eval command for this. I would recommend against this though, because there's a lot of pitfalls using this approach. Debugging is hard(er), it implies some security risks (bad content in the DB gets executed, uh oh).
See When is eval evil in php? for instance. Google for Eval is Evil, and you'll find a lot of examples why you should find another solution.
Addition: Another good article with some references to exploits is this blogpost. Refers to past vBulletin and phpMyAdmin exploits which were caused by improper Eval usage.
Easy:
$x // your variable with the data from the DB
<?php echo eval("?>".$x."<?") ?>
Let me know, works great for me in MANY applications, can't help but notice that everyone is quick to say how bad it is, but slow to actually help out with a straight answer...
eval() function was covered in other responses here. I agree you should limit use of eval unless it is absolutely needed. Instead of having PHP code in db you could have just a class name that has method called, say, execute(). Whenever you need to run your custom PHP code just instantiate the class of name you just fetched from db and run ->execute() on it. It is much cleaner solution and gives you great field of flexibility and improves site security significantly.
You can look at the eval function in PHP. It allows you to run arbitrary PHP code. It can be a huge security risk, though, and is best avoided.
Have you considered using your Source Control system to store different forks for the various installations (and the modules that differ among them)? That would be one of several best practices for application configuration I can think of. Yours is not an unusual requirement, so it's a problem that's been solved by others in the past; and storing code in a database is one I think you'd have a hard time finding reference to, or being advised as a best practice.
Good thing you posted the clarification. You've probably unintentionally posed an answer in search of a suitable question.
Read php code from database and save to file with unique name and then include file
this easy way for run php code and debug it.
$uniqid="tmp/".date("d-m-Y h-i-s").'_'.$Title."_".uniqid().".php";
$file = fopen($uniqid,"w");
fwrite($file,"<?php \r\n ".$R['Body']);
fclose($file);
// eval($R['Body']);
include $uniqid;
How I did this is to have a field in the database that identified something unique about the block of code needing to be executed. That one word is in the file name of that code. I put the strings together to point to the php file to be included. example:
$lookFor = $row['page'];
include("resources/" . $lookFor . "Codebase.php");
In this way even if a hacker could access you DB he couldn't put malicious code straight in there to be executed. He could perhaps change the reference word, but unless he could actually put a file directly onto the server it would do him no good. If he could put files directly onto the server, you're sunk then anyway if he really wants to be nasty. Just my two cents worth.
And yes, there are reasons you would want to execute stored code, but there are cons.