I have a class in a server1.
FILE1 in server1
<?php
class myObject
{
public function __construct()
{
echo 'Hello, World';
}
}
?>
FILE 2 in server2
$section = require('http://xx.xxx.xxx.x/plugins/myObject.php');
$intance = new myObject();
When file2 is called from a php file in server1 itself, Object is created. I can see 'Hello World' in browser.
But it fails when file2 is called from server2. I get fatal error class not found. I have tried include/file_get_contents/read/ __autoload /spl_autoload_register methods also. Nothing helps to invoke my class from another server.
Is this possible? Can anyone please suggest an alternative? Please help
UPDATE:
i have fopen and include url on in server2 from where iam trying to include file. Actually I needed the class and my website to be two servers.
SCENARIO:
I am tring to build a wallet website in server2. I have necessary plugins in another server [s1]. I have written a class file interacting with plugins in server 1 itself. Iam planning to have wallet websites in more servers. but all of these websites will interact with class in server1. If I could somehow get the code in that class to my website, then i could create objects and call class methods from other servers also. Please suggest other way to implement this.
UPDATE 2:
Can I build somthing like API where all my websites will send request to main class in S1 and get get response. An example would be helpful
Is this possible?
No. PHP code never leaves the server. That's why there are dependency management tools like Composer.
If you want to run code on server 2 from server 1 you need to implement a webservice that does that. So server 2 "calls" the php file on server 1 it does not "require" it. Try something like this:
File 1 Server 1
<?php
class myObject
{
public function __construct()
{
echo json_encode(['result'=>'really cool data result'])
}
}
new myObject();
?>
File 2 Server 2:
<?php
set_time_limit(0);
$url = "http://xx.xxx.xxx.x/plugins/myObject.php";
$ch = curl_init();
// Disable SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Will return the response, if false it print the response
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set the url
curl_setopt($ch, CURLOPT_URL,$url);
// Execute
$result_json=curl_exec($ch);
// Closing
curl_close($ch);
$result_obj = json_decode($result_json);
$result = $result_obj->result
If you want to run code on server 1 you have to do it like this and then use the result from server 1 and do something with it on server 2. You cannot run code on server 2 using software that exists on server 1 because by definition you cannot run something on one machine that exists on another machine.
You may need to first download the file and then requireing it.
No you can't do that. And even if there are really bad work arounds to do that, you should NEVER do that.
It makes your code very vulnerable, if you care about security.
Can you require from remote file? No. Can you include from remote file? Yes. This is known as Remote File Inclusion and usually it is considered a security risk. From PHP's documentation of include:
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.
To use this feature, open your php.ini file and set the allow_url_include as 1 or "On".
After that, you can now do
$section = include('http://xx.xxx.xxx.x/plugins/myObject.php');
$intance = new myObject();
Be warned though, if you allow a user to manipulate the argument to include, he would be able to inject arbitrary PHP code.
Related
I am running a PHP site on Windows using Wampserver. All throughout the site there is a hardcoded line such as:
$settings = parse_ini_file("/usr/local/apache2/myconfigs/settings.ini", true);
I know this is bad practice to begin with but it is out of my control.
When the site runs is there any possible way I can trick the site to point to C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini whenever the code is looking for /usr/local/apache2/myconfigs/settings.ini in the parse_ini_file function?
$settings = parse_ini_file(APACHE_INI_PATH, true);
// $settings = parse_ini_file("/usr/local/apache2/myconfigs/settings.ini", true);
This is a bit hackish but I think it's what you are looking for, so the trick here is to redefine the parse_ini_file function and make it ignore the invalid passed path ("/usr/local/apache2/myconfigs/settings.ini") and use your correct file instead.
This seems straightforward but a bit tricky since your new function should also call the original parse_ini_file function somehow, that's why you need to rename it first then override it
You will need PHP runkit extension enabled for this, have look at runkit_function_redefine and runkit_function_rename for reference.
Untested but should work, the code should be something around these lines :
runkit_function_rename('parse_ini_file','original_parse_ini_file');
runkit_function_redefine('parse_ini_file', function() {
original_parse_ini_file("C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini", true);
});
Make sure the code above is executed at the start of your application script and any parse_ini_file call should use your file instead of the hardcoded one.
If there is no single entry point to your application where you can put the code above, you can put it in a separate script and make PHP load before running any script via the auto_prepend_file setting in your settings.ini file, also make sure that runkit.internal_override is set to On since parse_ini_file is not a user defined function.
Hello please check this
runkit_function_rename('parse_ini_file','o_parse_ini_file');
runkit_function_redefine('parse_ini_file', function($p1,$p2) use($someCondition) {
if($someCondition)
o_parse_ini_file("C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini", true);
else
o_parse_ini_file($p1,$p2);
});
it can return
Call to undefined function runkit_function_rename()
to fix this error please read here
or here
If you don't want to do a find and replace as suggested by #cddoma, I propose that you create the directory /usr/local/apache2/myconfigs/ in your windows machine, and copy the file settings.ini from C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini to that directory.
Open your windows command line and enter the following
mkdir C:\usr\local\apache2\myconfigs\
copy C:\wamp64\bin\apache\apache2.4.27\myconfigs\settings.ini C:\usr\local\apache2\myconfigs\
you may be able to do this with a Symbolic link on Windows
I am using Birt 4.5 and PHP/MYSQL.
I am able to run birt reports with php. I have enabled tomcat and copied 'birt-runtime-4_5_0/WebViewerExample' to tomcat/webapps and renamed it to birt.
So I can run birt viewer with php;
<?php
$fname = "report/test.rptdesign&__showtitle=false";
$dest = "http://localhost:8081/birt/frameset?__report=";
$dest .= $fname;
header("Location: $dest" );
?>
Above code is working fine. But report connectstring already saved in test.rptdesign file.
I want to remove DB login credentials from test.rptdesign file and assign it while report open with PHP.
I have tried with report parameters. But all the parameters will display on browser address-bar.
Is there any secure way to do this? This is very important when we need to change the database location. It is very hard to change the data source of each and every .rptdesign file.
Thank You,
Supun
I don't believe using report parameters to handle a database connection is the right way. In addition to the address-bar problem you mentionned, it will cause unexpected issues: for example you won't be able to use this database to feed the dataset of another report parameter.
With Tomcat the best approach is to externalize the database connection in a connection pool: easy, robust, and reports might run significantly faster.
Alternatively the datasource can be externalized in a BIRT library (.rptlibrary) and shared across all report-designs: thus only the library needs to be updated when the database location is changing.
I agree with Dominique that sending the database parameters via the query is most likely an inappropriate solution - and you've not given any explanation of whether this is a requirement of the system.
But it is quite trivial to proxy the request via PHP and decorate the URL with the required parameters, something like...
<?php
$_GET['__showtitle']=$_GET['__showtitle'] ? $_GET['__showtitle'] : 'false';
$_GET['__report']=$fname; // NB this should be NULL in your code!
$_GET['dbuser']='a_db_user';
$_GET['passwd']='s3cr3t';
$qry=http_build_query($_GET);
$url="http://localhost:8081/birt/frameset?" . $qry;
// if its simply returning HTML, then just....
$fin=fopen($url, 'r');
while ($l=fgets($fin)) {
print $l;
}
exit;
If the returned content contains relative links the you'll need to rewrite the output stream. If the content type is unusual or you want to project other headers (e.g. for caching) to the browser, then you'll need to use Curl, capture the headers and relay them.
My problem is I need to fetch FOOBAR2000's title because that including information of playing file, so I create a execute file via Win32 API(GetWindowText(), EnumWindows()) and it's working good.
TCHAR SearchText[MAX_LOADSTRING] = _T("foobar2000");
BOOL CALLBACK WorkerProc(HWND hwnd, LPARAM lParam)
{
TCHAR buffer[MAX_TITLESTRING];
GetWindowText(hwnd, buffer, MAX_TITLESTRING);
if(_tcsstr(buffer, SearchText))
{
// find it output something
}
return TRUE;
}
EnumWindows(WorkerProc, NULL);
Output would look like "album artis title .... [foobar2000 v1.1.5]"
I created a php file like test.php, and use exec() to execute it.
exec("foobar.exe");
then in console(cmd) I use command to execute it
php test.php
It's working good too, same output like before.
Now I use browser(firefox) to call this php file(test.php), strange things happened.
The output only foobar2000 v1.1.5, others information gone ...
I think maybe is exec() problem? priority or some limitation, so I use C# to create a COM Object and register it, and rewrite php code
$mydll = new COM("FOOBAR_COMObject.FOOBAR_Class");
echo $mydll->GetFooBarTitle();
still same result, command line OK, but browser Fail.
My question is
Why have 2 different output between command line and browser. I can't figure it out.
How can I get correct output via browser.
or there is a easy way to fetch FOOBAR2000's title?
Does anyone have experience on this problem?
== 2012/11/28 edited ==
follow Enno's opinion, I modify http_control plug-in to add filename info, original json info is "track title".
modify as following
state.cpp line 380 add 1 line
+pb_helper1 = pfc::string_filename(pb_item_ptr->get_path());
pb_helper1x = xml_friendly_string(pb_helper1);
# 1: when firefox opens the php and it gets executed, it the context depends on the user which runs the php-container (apache), this is quite different from the commandline call which gets executed in your context
# 2 and 3: there seems to be more than one way for getting the title: use the foobar-sdk and create a module which simply reads the current title per api, then write your result in an static-html-document inside your http-root-folder OR use the http-client inside the sdk, with it, you do not need a wabserver, even better use a already implemented module: for instance foo_upnp or foo-httpcontrol
Good luck!
If your webserver runs as a service, in windows you need to enable "allow desktop interaction" for the service. Your php script runs as a child of the webserver process when requested via browser.
I have the line
xmlhttp.open("GET","file.php?id=4",true);
This does not work since file.php is not in the same folder but rather in a different private folder not visible to the public.
Is there a way to use the open function to open a file in a different folder?
That's fundamentally impossible.
If you want to send an HTTP request to it, it must be visible to the public over HTTP.
You can only request files from within the public webspace. To access files outside the public webspace you need a script in the public webspace that can fetch the contents from the private folder, e.g.
<?php // file.php in the public webspace
$allowedFiles = array(
1 => '/path/to/private/space/on/server/file1.txt',
2 => '/path/to/private/space/on/server/file2.txt',
3 => '/path/to/private/space/on/server/file3.txt',
4 => '/path/to/private/space/on/server/file4.txt',
);
$id = filter_var($_GET['id'], FILTER_VALIDATE_INT);
if (isset($allowedFiles[$id])) {
readfile($allowedFiles[$id]);
}
Now when you do
xmlhttp.open("GET","file.php?id=4",true);
the script will send the content of
/path/to/private/space/on/server/file4.txt
to the client.
Edit regarding some comments:
Note that readfile will not execute the file contents. If you need to send the results of a PHP script, you have to use include instead of readfile. Please refer to the Manual for details.
The above approach is effectively the same as most of the frameworks nowadays use. You have one single script that acts as a gateway into your application (kind of like a Front Controller pattern). This script accepts any and all requests (think mod_rewrite) to your application and is the only publicly accessible PHP file. It will bootstrap your application and then determine from the URL (or whatever you seem fit) what file, usually a controller when using MVC, in the private space should be instantiated and called.
How can include a external class in a php file?
example:
//Test.class.php
<?php
class Test{
function print($param){
echo $param;
}
}
?>
//######################################################
//test.php
<?php
include('http://www.test.com/Test.class.php');
$obj = new Test();
echo $obj->print("hola");
?>
The class is on another server. I have enabled the allow_url_include and allow_url_fopen.
Why can't I call the function print?
The remote file must output the php source code, not execute it.
To output the PHP code instead of executing you could simply remove the .php extension from the file.
PS: Are you really, really, really sure you need remote inclusion? It's a BIG security risk!
What you're including from the other server isn't the code behind the PHP but the output from it (if you visit that page in a browser you aren't seeing the PHP code if you view source right?)
You either need to reconfigure the other server not to execute the code but display it (not a good idea if it's in any way shared or needs to execute it's own code), or rename the other file to something that isn't first interpretted (try otherfile.php.txt)
Have a look at the documentation:
(...) 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.
Probably the server, you are trying to get the file from, executes the PHP file and only the result (which is empty) is included. You would have to configure the server in such a way that it outputs the PHP code. But this is not a good idea if it is sensible code.