I've been wanting to do this because my site does about 3 HTTP requests per page load, because each PHP's output is retrieved with cURL. This is too slow, and I want to avoid using cURL. I found this question on Stack Overflow, and it basically does what I want. The accepted answer's suggestion is to use ob_start(); to start getting output then use ob_get_clean(); to put the output into a variable. My issue now is that the PHP scripts I'm trying to capture output from need variables passed to them using HTTP Get. The access those variables like this:
$term = $_GET['term'];
And I don't want to change that, because although I'm going to access these PHP scripts' outputs from another PHP script, I'm also planning on accessing them from elsewhere. So, is there a way to fool these PHP scripts into accepting some arguments through Get, then capturing their outputs with the method suggested above?
You can $_GET variables from any php script if its set (use isset to check that). Then just cURL to such url's will work.
If you have changed the method to POST earlier, you can use CURLOPT_HTTPGET. See the curl_setopt functions page (http://www.php.net/manual/en/function.curl-setopt.php) for more details.
For a non-cURL method, use jQuery ajax. It is quite simple to use, just read the documentation here.
EDIT: This is what you wanted (haven't checked the code though)
<?php
function get_include_contents($filename, $get) {
if (is_file($filename)) {
ob_start();
$_GET = array();
while (list($key, $val) = each($get)) {
$_GET[$key]=$val;
}
include $filename;
return ob_get_clean();
}
return false;
}
$string = get_include_contents('somefile.php', array('param1'=>'x', 'param2'=>'y'));
?>
And I don't want to change that, because although I'm going to access these PHP scripts' outputs from another PHP script, I'm also planning on accessing them from elsewhere. So, is there a way to fool these PHP scripts into accepting some arguments through Get, then capturing their outputs with the method suggested above?
Your question is a bit unclear as to why you're using cURL in the first place. If your scripts are on the same server, you can simply set the correct $_GET variables and use:
<?php
ob_start( );
// include the file.
$_GET['foo'] = 'bar';
include 'the_file.php';
$output = ob_get_clean( );
If your scripts are located on another server, where include is not viable, you will always have to do a HTTP request to get their contents, regardless of whether your this with cURL or Ajax, or sockets for all I care.
well you can access a $_GET from any script loaded as long as its in the URI, the variable $term can be used in any script. You can also include the script.
When you include a script you can access some of its content after the include.
Related
I am new to PHP and very likely I am using the incorrect approach because I am not used to think like a PHP programmer.
I have some files that include other files as dependencies, these files need to have global code that will be executed if $_POST contains certain values, something like this
if (isset($_POST["SomeValue"]))
{
/* code goes here */
}
All the files will contain this code section, each one it's own code of course.
The problem is that since the files can be included in another one of these files, then the code section I describe is executed in every included file, even when I post trhough AJAX and explicitly use the URL of the script I want to POST to.
I tried using the $_SERVER array to try and guess which script was used for the post request, and even though it worked because it was the right script, it was the same script for every included file.
Question is:
Is there a way to know if the file was included into another file so I can test for that and skip the code that only execute if $_POST contains the required values?
Note: The files are generated using a python script which itself uses a c library that scans a database for it's tables and constraints, the c library is mine as well as the python script, they work very well and if there is a fix for a single file, obviously it only needs to be performed to the python script.
I tell the reader (potential answerer) about this because I think it makes it clear that I don't need a solution that works over the already existant files, because they can be re-generated.
From the sounds of it you could make some improvements on your code structure to completely avoid this problem. However, with the information given a simple flag variable should do the trick:
if (!isset($postCodeExecuted) && isset($_POST["SomeValue"]))
{
/* code goes here */
$postCodeExecuted = true;
}
This variable will be set in the global namespace and therefore it will be available from everywhere.
I solved the problem by doing this
$caller = str_replace($_SERVER["DOCUMENT_ROOT"], "", __FILE__);
if ($_SERVER["REQUEST_METHOD"] === "POST" and $caller === $_SERVER["PHP_SELF"])
performThisAction();
Let's say I have a PHP file some_function.php which I can run with file_get_contents('some_function.php?' . $parameters_string) (or any similar function). The parameters to this function can be given via either GET or POST HTTP method.
Instead I could include needed file and use this function within one script.
I could figure out that it could be reasonable if I need to run a separate process or I need this function to be on a separate server. But if not, is there any reasons not to do it? May be this call will be much slower? Anything else I should take into account?
I know that I will not be able to use global variables (which I assume as a bad coding style anyway).
By using file_get_contents() you will not be actually calling the function in question but will make an HTTP request passing some predefined parameters which will then be passed on the function in your code.
Using include() you could have a library of classes or functions inside that file, and call them directly as needed and as many times as needed.
EXAMPLE:
library.php
function my_function_1() { }
function my_function_2() { }
index.php
include('library.php');
my_function_1(); // call the first function
my_function_2(); // call the second function
my_function_1(); // call the first function again, just because we can
You wouldn't be able to do that through the HTTP request and even if you did hardcode your some_function.php file to do some functionality like above, you would end up with really bad code that would be hard to customize to your needs and near impossible to maintain once it gets bigger.
You cannot pass a query string via a local file_get_contents call as shown.
If you use file_get_contents on a remote HTTP URL, you will be able to use a query string, but this will be significantly slower than a local include or file_get_contents.
You can, incidentally, still include something that needs $_GET/$_POST variables:
<?php
$_GET['something'] = true;
include('something.php');
This function is returning the content of the file rather the result of fetch_link_settings_overide() within it.
The issue is not with the overide function as after the initial error I commented out my modification just to be sure it wasn't something I had done there.
function fetch_link_settings(){
include( plugins_url()."/plugin-child/plugin_overrides.php");
return fetch_link_settings_override();
}
Adding the content of the derived function plugin-child/plugin_overrides.php as we are not getting anywhere currently.
function fetch_link_settings_override(){
global $post;
// If the destination url is set by the user, use that. Otherwise, use the permalink
$destination_url = get_post_meta($post->ID, '_promo_slider_url', true);
// ASAdd additional place to look in the case of the post being via the PODS advert track
if( ! $destination_url )
$destination_url = get_post_meta($post->ID, 'okd_advert_link', true);
if( ! $destination_url )
$destination_url = get_permalink($post->ID);
// If the target attribute is set by the user, use that. Otherwise, set it to _self
$target = get_post_meta($post->ID, '_promo_slider_target', true);
if( ! $target ) $target = '_self';
// Setup the disable links variable
$disable_links = get_post_meta($post->ID, '_promo_slider_disable_links', true);
return compact('destination_url', 'target', 'disable_links');
}
You write this:
include( plugins_url()."/plugin-child/plugin_overides.php");
Why is plugins_url() there? The include function is strictly based on the file system:
The `include` statement includes and evaluates the specified file.
As explained in the WordPress docs, the plugins_url() would give you the full web URL which is 100% different than the file system WordPress is installed on:
Retrieves the absolute URL to the plugins directory (without the
trailing slash) or, when using the $path argument, to a specific file
under that directory.
So perhaps it should be like this:
include("/plugin-child/plugin_overides.php");
Or perhaps you need the plugin_dir_path()?
include(plugin_dir_path( __FILE__ ) . "/plugin-child/plugin_overides.php");
But that seems wrong. Where would /plugin-child/plugin_overides.php? Try doing this:
include("/full/path/to/wordpress/and/this/plugin-child/plugin_overides.php");
Just replace /full/path/to/wordpress/and/this/ with the actual file system path to /plugin-child/plugin_overides.php.
EDIT: Since the original poster is persistent in using plugins_url() despite all of the suggestions otherwise, here is my detailed response:
…you said “you cannot load raw functions via a URL with include” well
this is not relevant because even if I add $some_var = 'smith'; as the
first statement in the included file, it is not visible in the
function using the include.
Apologies. Functions, classes, strings, constants… Just about anything that you want to be raw, unprocessed PHP will simply not be passed via an http:// or https:// URL because Apache will parse the PHP instructions & simply return the output of that file and not the raw, unprocessed contents of the PHP in that file.
Additionally the original poster contents the following:
You can’t help me because what you are saying does not make sense or
you are not explaining yourself adequately. Look at these examples:
include realpath(dirname(FILE) . "/" . "relative_path");
include("data://text/plain;base64,".base64_encode($content));
include("data://text/plain,".urlencode($content));
All taken from the official PHP documentation. They all use
functions returning components that are concatenated with the rest of
the url. I also tried this typing the filepath explicitly and the
result is the same.
The examples cited are as follows:
include realpath(dirname(FILE) . "/" . "relative_path");
This is a filesystem level include which is the most common way PHP files are included into other files.
include("data://text/plain;base64,".base64_encode($content));
include("data://text/plain,".urlencode($content));
These are both data URLs. Not http or https. So again when you use plugins_url() what you are getting is a full http:// or https:// URL in which Apache parses the PHP instructions & simply return the output of that file and not the raw, unprocessed contents of the PHP in that file. Or as very clearly explained in the PHP documentation you are linking to; emphasis mine:
If "URL include wrappers" are enabled in PHP, you can specify the file
to be included using a URL (via HTTP or other supported wrapper - see
Supported Protocols and Wrappers for a list of protocols) instead of a
local pathname. If the target server interprets the target file as PHP
code, variables may be passed to the included file using a URL request
string as used with HTTP GET. This is not strictly speaking the same
thing as including the file and having it inherit the parent file's
variable scope; the script is actually being run on the remote server
and the result is then being included into the local script.
Going back to your example, you say now the contents of plugin_overides.php is $some_var = 'smith';. How exactly? If it is a PHP file like this:
<?php
$some_var = 'smith';
?>
When you call that file via a URL generated by the following code:
include(plugins_url() . "/plugin-child/plugin_overrides.php");
Assuming your website is http://some.cool.website/ the you are basically making a call like this:
http://some.cool.website/plugin-child/plugin_overides.php
So the output of plugin_overides.php would be 100% blank. If you wanted to get output of that file, you could do the following:
<?php
$some_var = 'smith';
echo $some_var;
?>
And that would return smith. Meaning the absolute ONLY output you would get from that call is pure text. Nothing else.
Now I see you actually have posted the contents of plugin_overides.php. My example explanation above is still apt, but still a basic question. This is your function; just the interface & return for example:
function fetch_link_settings_override(){
// Other code removed. Just a structural illustration for now.
return compact('destination_url', 'target', 'disable_links');
}
Do you actually call fetch_link_settings_override() in plugin_overides.php when it runs? Well, if that function does not run, then there is 100% no way you will ever get any output. But assuming good faith, look at your return statement here:
return compact('destination_url', 'target', 'disable_links');
If you are returning compact, then you are returning an array. You cannot simply return a bare array as a URL call like this http://some.cool.website/plugin-child/plugin_overides.php. The output at most would be simply the word Array.
If the goal is to take that array & do something, then you should use json_encode in fetch_link_settings_override and then use json_decode on the receiving side of that. So the return statement would be something like this:
return json_encode(compact('destination_url', 'target', 'disable_links'));
I'm using curl in PHP to return the content of a PHP file. I want to do this locally because I will be accessing multiple PHP files during the same script, so it would be faster to open the file directly.
However, I want to be able to push parameters into the PHP files (treat them exactly as PHP files on the web, but grabbing them locally), as I want to push parameters into the scripts which will be generating additional dynamic content when I grab it.
Is this possible to do if I call the files locally? I've tried using the file:///, calling the file directly, but this won't run the PHP code found in these files.
Any ideas?
edit
Sorry for the confusion:
-This is currently running on a webserver, and I am currently calling http:// (and not file:///) so the PHP contained in those files can be executed. However, I find this to be slow because I'm generating multiple curl() calls that are essentially calling the server itself multiple times.
you can do trick like:
function php_to_string($php_file, $new_GET = false, $new_POST = false) {
// replacing $_GET, $_POST if necessary
if($new_GET) {
$old_GET = $_GET;
$_GET = $new_GET;
}
if($new_POST) {
$old_POST = $_POST;
$_POST = $new_POST;
}
ob_start();
include($php_file);
// restoring $_GET, $_POST if necessary
if(isset($old_GET)) {
$_GET = $old_GET;
}
if(isset($old_POST)) {
$_POST = $old_POST;
}
return ob_get_clean();
}
$content = php_to_string('my_file.php');
$content = php_to_string('my_file.php', Array('id'=>23)); // http://localhost/my_fie.php?id=23
But please mind it may overwrite your existing variables, causing bugs (for example duplicate defines) etc. so you may use sandbox solution
I believe you would want to set up a web server (e.g. Apache) on your local machine so you can go to http://localhost/script.php?param1=foo¶m2=bar instead of file:///path/to/script.php. The difference is that when you do file:///, the files are just opened, but if you go through Apache, the scripts are actually executed.
As for passing arguments to your scripts, use the query string for that (e.g. ?param1=foo, etc.).
I don't know why you're doing what you're doing, but hopefully that helps you do it.
I have a php file on my server that takes in two inputs through the URL and then comes back with a result. When a page is loaded, I'd like to have the result of that calculation already loaded. For example:
$var = load("http://mysite.com/myfile.php?&var1=var1&var2=var2");
I know that load isn't a real function for this, but is there something simple that suits what I'm looking for? thanks
Use file_get_contents
$foo = file_get_contents('http://mysite.com/myfile.php?&var1=var1&var2=var2');
Or, a better solution if the file is located on your server:
include('myfile.php');
and either set the $_GET variables in the included script itself, or prior to including it.
If they are running on the same server, consider calling the script directly?
$_GET["var1"] = "var1";
$_GET["var2"] = "var2";
include "myfile.php";
You could use file_get_contents, but it may be a more practical solution to simply include the file and call the function directly in the file, rather than trying to manually load the file.