I'm not a PHP developer, but I'm currently hacking on an internal tool so my team can take advantage of its goodness. There's an index file that looks like so:
require( ($loader_path = "../../loaderapi/") . "loader.php" );
Used like this, $loader_path will retain its value within the loader.php file.
However, we want to access this API from our team's server like so:
require( ($loader_path = "http://remoteservername/loaderapi/") . "loader.php" );
In this case the $loader_path variable doesn't retain its value. I'm guessing it has something to do with it being a full blown URL, but I might be wrong. Any idea on how I can make this work, or why I can't do it this way?
If your accessing a PHP script over HTTP, only the output of that script is returned. So your script will try to interpret the output of that remote PHP script and not its source.
If there is a connection over the file system, you may want to try file://remoteservername/loaderapi/loader.php instead.
NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO!
Remote file inclusion is a BAD idea, probably one of the biggest security flaws you can open up. Even for an internal tool this is not acceptable even if only purely for contributing bad habits.
PHP by default disables this behavior, and there is a broad push to have the ability to perform an include on a URL completely stripped from PHP (as there is no compelling reason to have this ability).
If you want to load shared resources, go through a shared file system drive (as in, don't use http, ftp, anything but file://) or better yet distribute copies of loader.php through a version control system. Loading from a single file resource opens you up to problems in the future of say a new dev overwriting loader.php and breaking everyone else's code.
There shouldn't be any real difference between the two; what you're doing is defining $loader_path, concatenating the loader.php, and passing that to require.
HOWEVER: you're defining the variable within the scope of a require, which will halt processing of the script of require fails.
Try replacing 'require' with 'include' and see if it retains the variable.
Also, note that if you are running your PHP server on a windows machine, and the php version is less than 4.3.0, neither 'require' nor 'include' can handle remote files : http://us.php.net/manual/en/function.include.php
Also, as noted before, if the .php lives on a remote server that parses php, you will not get code, but the result of the remote server processing the code. You'll either have to serve it up as a .txt file, or write php that, when processed, outputs valid php.
Have you tried splitting it into two lines:
$loader_path = "http://remoteservername/loaderapi/";
require( $loader_path . "loader.php" );
It's easier to read this way as well.
Simplify the code reading by simply putting everything on 3 lines:
$loader_path = "http://remoteservername/loaderapi/";
$page = "loader.php";
require($loader_path . $page );
Much clearer and it works.
why not just put it above the require statement? would make it easier to read too.
<?php
$loader_path = "../../folderName/"
require($loader_path . "filename")
?>
Related
I have a PHP routing script, like this:
include_once('routing-functions.php');
// pathMatches was imported from routing-functions.php
if(pathMatches('/blog/*')){
include_once('actual-script.php');
}
The problem I have is the following: the functions and global variables from routing-functions.php could potentially conflict with the included file. Additionally, I don't want actual-script.php to have access to any of the variables of the router.
I am looking for a way to completely wipe the PHP context, so that the file is included as if it were directly requested, so doing the following is not an option because it changes the context/scope in which actual-script.php is executed:
if(pathMatches('/blog/*')){
function $sandbox(){
include_once('actual-script.php');
};
$sandbox();
}
Additionally, sending a local request to the file (e.g. with cURL) is also not an option, because it has a negative impact on performance and I want it to run as if it were under the /blog/ URL.
The problem is easy to solve with .htaccess, however, I need a dynamic solution that uses a PHP router.
If anyone has had a similar problem before or knows of a good solution it would be greatly appreciated.
can some one tell me what this following code does and what is the problem here in terms of security?
< ?php require_once '../include/' . $_GET['file']?>
i think that this _Get['file'] gets an argument and includes into the library i guess? im not sure, and also not sure about the problem in this code.
This allows the client to make the webserver execute almost any PHP script on the server. They can even execute files outside the ../include directory by including their own ../ sequences in the parameter, e.g.
yourscript.php?file=../../../somescript.php
This will then execute
require_once("../include/../../../somescript.php");
which is equivalent to
require_once("../../somescript.php");
From a tutorial I read on Sitepoint, I learned that I could load JS files through PHP (it was a comment, anyway). The code for this was in this form:
<script src="js.php?script1=jquery.js&scipt2=main.js" />
The purpose of using PHP was to reduce the number of HTTP requests for JS files. But from the markup above, it seems to me that there are still going to be the same number of requests as if I had written two tags for the JS files (I could be wrong, that's why I'm asking).
The question is how is the PHP code supposed to be written and what is/are the advantage(s) of this approach over the 'normal' method?
The original poster was presumably meaning that
<script src="js.php?script1=jquery.js&scipt2=main.js" />
Will cause less http requests than
<script src="jquery.js" />
<script src="main.js" />
That is because js.php will read all script names from GET parameters and then print it out to a single file. This means that there's only one roundtrip to the server to get all scripts.
js.php would probably be implemented like this:
<?php
$script1 = $_GET['script1'];
$script2 = $_GET['script2'];
echo file_get_contents($script1); // Load the content of jquery.js and print it to browser
echo file_get_contents($script2); // Load the content of main.js and print it to browser
Note that this may not be an optimal solution if there is a low number of scripts that is required. The main issue is that web browser does not load an infinitely number of scripts in parallel from the same domain.
You will need to implement caching to avoid loading and concatenating all your scripts on every request. Loading and combining all scripts on every request will eat very much CPU.
IMO, the best way to do this is to combine and minify all script files into a big one before deploying your website, and then reference that file. This way, the client just makes one roundtrip to the server, and the server does not have any extra load upon each request.
Please note that the PHP solution provided is by no means a good approach, it's just a simple demonstration of the procedure.
The main advantage of this approach is that there is only a single request between the browser and server.
Once the server receives the request, the PHP script combines the javascript files and spits the results out.
Building a PHP script that simply combines JS files is not at all difficult. You simply include the JS files and send the appropriate content-type header.
When it gets more difficult is based on whether or not you want to worry about caching.
I recommend you check out minify.
<script src="js.php?script1=jquery.js&scipt2=main.js" />
That's:
invalid (ampersands have to be encoded)
hard to expand (using script[]= would make PHP treat it as an array you can loop over)
not HTML compatible (always use <script></script>, never <script />)
The purpose of using PHP was to reduce the number of HTTP requests for JS files. But from the markup above, it seems to me that there are still going to be the same number of requests as if I had written two tags for the JS files (I could be wrong, that's why I'm asking).
You're wrong. The browser makes a single request. The server makes a single response. It just digs around in multiple files to construct it.
The question is how is the PHP code supposed to be written
The steps are listed in this answer
and what is/are the advantage(s) of this approach over the 'normal' method?
You get a single request and response, so you avoid the overhead of making multiple HTTP requests.
You lose the benefits of the generally sane cache control headers that servers send for static files, so you have to set up suitable headers in your script.
You can do this like this:
The concept is quite easy, but you may make it a bit more advanced
Step 1: merging the file
<?php
$scripts = $_GET['script'];
$contents = "";
foreach ($scripts as $script)
{
// validate the $script here to prevent inclusion of arbitrary files
$contents .= file_get_contents($pathto . "/" . $script);
}
// post processing here
// eg. jsmin, google closure, etc.
echo $contents();
?>
usage:
<script src="js.php?script[]=jquery.js&script[]=otherfile.js" type="text/javascript"></script>
Step 2: caching
<?php
function cacheScripts($scriptsArray,$outputdir)
{
$filename = sha1(join("-",$scripts) . ".js";
$path = $outputdir . "/" . $filename;
if (file_exists($path))
{
return $filename;
}
$contents = "";
foreach ($scripts as $script)
{
// validate the $script here to prevent inclusion of arbitrary files
$contents .= file_get_contents($pathto . "/" . $script);
}
// post processing here
// eg. jsmin, google closure, etc.
$filename = sha1(join("-",$scripts) . ".js";
file_write_contents( , $contents);
return $filename;
}
?>
<script src="/js/<?php echo cacheScripts(array('jquery.js', 'myscript.js'),"/path/to/js/dir"); ?>" type="text/javascript"></script>
This makes it a bit more advanced. Please note, this is semi-pseudo code to explain the concepts. In practice you will need to do more error checking and you need to do some cache invalidation.
To do this is a more managed and automated way, there's assetic (if you may use php 5.3):
https://github.com/kriswallsmith/assetic
(Which more or less does this, but much better)
Assetic
Documentation
https://github.com/kriswallsmith/assetic/blob/master/README.md
The workflow will be something along the lines of this:
use Assetic\Asset\AssetCollection;
use Assetic\Asset\FileAsset;
use Assetic\Asset\GlobAsset;
$js = new AssetCollection(array(
new GlobAsset('/path/to/js/*'),
new FileAsset('/path/to/another.js'),
));
// the code is merged when the asset is dumped
echo $js->dump();
There is a lot of support for many formats:
js
css
lot's of minifiers and optimizers (css,js, png, etc.)
Support for sass, http://sass-lang.com/
Explaining everything is a bit outside the scope of this question. But feel free to open a new question!
PHP will simply concatenate the two script files and sends only 1 script with the contents of both files, so you will only have 1 request to the server.
Using this method, there will still be the same number of disk IO requests as if you had not used the PHP method. However, in the case of a web application, disk IO on the server is never the bottle neck, the network is. What this allows you to do is reduce the overhead associated with requesting the file from the server over the network via HTTP. (Reduce the number of messages sent over the network.) The PHP script outputs the concatenation of all of the requested files so you get all of your scripts in one HTTP request operation rather than multiple.
Looking at the parameters it's passing to js.php it can load two javascript files (or any number for that matter) in one request. It would just look at its parameters (script1, script2, scriptN) and load them all in one go as opposed to loading them one by one with your normal script directive.
The PHP file could also do other things like minimizing before outputting. Although it's probably not a good idea to minimize every request on the fly.
The way the PHP code would be written is, it would look at the script parameters and just load the files from a given directory. However, it's important to note that you should check the file type and or location before loading. You don't want allow a people a backdoor where they can read all the files on your server.
I really have read the other articles that cover this subject. But I seem to be in a slightly different position. I'm not using modrewrite (other articles).
I would like to 'include' a webpage its a 'Joomla php' generated page inside a php script. I'd hoped to make additions on the 'fly' without altering the original script. So I was going to 'precomplete' elements of the page by parasing the page once it was included I hadent wanted to hack the original script. To the point I can't include the file and its not because the path is wrong -
so
include ("/home/public_html/index.php"); this would work
include ("/home/public_html/index.php?option=com_k2&view=item&task=add"); this would not!
I've tried a variety of alternates, in phrasing, I can't use the direct route "http:etc..." since its a current php version so must be a reference to the same server. I tried relative, these work without the ?option=com_k2&view=item&task=add
It may be the simple answer that 'options' or variables can be passed.
Or that the include can't be used to 'wait' for a page to be generated - i.e. it will only return the html.
I'm not the biggest of coders but I've done alot more than this and I thought this was so basic.
this would work include ("/home/public_html/index.php?option=com_k2&view=item&task=add"); this would not!
And it never will: You are mixing a filesystem path with GET parameters, which can be passed only through the web server (utilizing a http:// call... But that, in turn, won't run the PHP code the way you want.)
You could set the variables beforehand:
$option = "com_k2";
$view = "item";
$task = "add";
include the file the normal way:
include ("/home/public_html/index.php");
this is assuming that you have access to the file, and can change the script to expect variables instead of GET parameters.
It's functionality is so strong that I worry about its stability and performance.
What do you think?
UPDATE
What I'm doing is this:
$old_dir = getcwd();
chdir( dirname($included_file) );
include ( $included_file );
chdir( $old_dir );
Essentially it just does include ( $included_file );,but inside that $included_file it can't find 3.php which is in the same directory as itself is in,so I manually set the cwd and it works.But it would be nice if I find the reason why it can't find.As for why debug_backtrace is needed,it's because 3.php is included by another func,since the relative path doesn't work,it has to use debug_backtrace to get the including file path,finally using the absolute path as mentioned below.
It's not easy to reproduce,as the above code is in the context of a method,and much more..If no one else has met this kinda problem I'd like to just stop here,anyway,the cost is just the 3 extra lines,not a big deal.
debug_backtrace is relatively expensive in my experience, so you should be careful it is not used in loops (e.g. in a custom error handler that catches warnings or notices and performs a backtrace every time).
For any kind of error logging, I think it's pretty invaluable, and because it's going to be called only once, definitely not a performance problem. It is surely always good to include a backtrace in an error report.
I can't see why there would be any specific issues with this function's stability (i.e. calling it causing another crash), I've never heard of any problems. The only "gotcha" I can see is this note in the User Contributed Notes when using objects as function parameters that have no _toString method defined.
Of course, you should never output the results of a backtrace to the end user - that goes without saying.
Well, considering its name, I'm not sure I would use it as a "normal" part of my application -- even though I don't remember having read anything which said that it was either good nor bad.
I don't really know what you mean about "serious usage", but :
If you need that function for your application to work, it migh indicate some problem in your design
This function can be useful in an error-handler, when you want to log how/where an error happened : it will make the log files more useful, when it comes to tracking down the sources of errors
Though, not sure that "error logging" corresponds to your definition of serious usage ?
Ok, from my understanding, the problem is following
You've got a php file, let's call it "main.php". In "main.php" you're including "A.php" from some directory:
# in "main.php"
include '/some/dir/A.php';
A.php, in turn, includes 'B.php', which is in the same directory as A.php
# in "A.php"
include 'B.php';
the problem: since "/some/dir/" (where A and B reside) is not the current for "main.php", php does not see B.php from A.php
the solution: in A.php use an absolute full path to /some/dir. Either hardcode it or obtain it dynamically via dirname(__FILE__)
# in "A.php"
include dirname(__FILE__) .'/B.php';