I understand that I can set the option on any specific instance, however what I would really like is to set something up php.ini or somewhere similar which will handle this across all projects and all instances.
Does anyone know a way for me to accomplish this?
EDIT:
I am particularly interested in a solution which will allow for the certificates to be in different locations on different servers.
I am developing on a Windows machine which needs this but deploying to a Linux server which not only doesn't need it but doesn't even have the path indicated.
I understand that I can use conditions to check where the code is running but would prefer to just have it work out of the box. It seems to me that this is really an issue for curl and PHP to handle rather than my code and hence the settings for it belong there.
I found the answer here (in the user notes): http://php.net/manual/en/function.curl-setopt.php
Just add this to you .ini (note: you cannot use ini_set, although I don't know why you would want to. Thanks #Carlton):
curl.cainfo=c:\php\cacert.pem
And get that file from: http://curl.haxx.se/docs/caextract.html
Works and you aren't opening yourself up for MITM attacks
Here is a patch to 'emulate' what we can see on linux when a valid crt data has been found at build time (which is the case for almost all distros):
http://www.php.net/~pierre/patches/curl_cacert_default.txt
it adds a (system) ini settings to define the path to the cacert, curl.cainfo=c:\curl\ca.crt
cacert data can be fetched here: http://curl.haxx.se/docs/caextract.html
DLL for php 5.3 can be found here: http://www.php.net/~pierre/test/curl-5.3-vc9-x86-ts-nts-cainfodefault.zip
DLL for php 5.2 can be found here: http://www.php.net/~pierre/test/curl-5.2-cainfodefault.zip
Please let me know how it works.
download cacert.pem add to folder php
copy url the place of file cacert.pem
[curl] curl.cainfo="C:/xampp/php/cacert.pem"
#Matt is right, but I would add that curl.cainfo is a PHP_INI_SYSTEM directive so you must set it in php.ini...using the ini_set function in a script will always return false as I found out after too many minutes of head banging
You could create a wrapper function which sets the option and use php.ini's auto_prepend_file to load the file it's defined in, but your code would have to be changed to use this wrapper function instead.
Example:
function my_curl_init($url=null) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CAINFO, getcwd().'/cert/ca.crt');
return $ch;
}
Related
I understand that I can set the option on any specific instance, however what I would really like is to set something up php.ini or somewhere similar which will handle this across all projects and all instances.
Does anyone know a way for me to accomplish this?
EDIT:
I am particularly interested in a solution which will allow for the certificates to be in different locations on different servers.
I am developing on a Windows machine which needs this but deploying to a Linux server which not only doesn't need it but doesn't even have the path indicated.
I understand that I can use conditions to check where the code is running but would prefer to just have it work out of the box. It seems to me that this is really an issue for curl and PHP to handle rather than my code and hence the settings for it belong there.
I found the answer here (in the user notes): http://php.net/manual/en/function.curl-setopt.php
Just add this to you .ini (note: you cannot use ini_set, although I don't know why you would want to. Thanks #Carlton):
curl.cainfo=c:\php\cacert.pem
And get that file from: http://curl.haxx.se/docs/caextract.html
Works and you aren't opening yourself up for MITM attacks
Here is a patch to 'emulate' what we can see on linux when a valid crt data has been found at build time (which is the case for almost all distros):
http://www.php.net/~pierre/patches/curl_cacert_default.txt
it adds a (system) ini settings to define the path to the cacert, curl.cainfo=c:\curl\ca.crt
cacert data can be fetched here: http://curl.haxx.se/docs/caextract.html
DLL for php 5.3 can be found here: http://www.php.net/~pierre/test/curl-5.3-vc9-x86-ts-nts-cainfodefault.zip
DLL for php 5.2 can be found here: http://www.php.net/~pierre/test/curl-5.2-cainfodefault.zip
Please let me know how it works.
download cacert.pem add to folder php
copy url the place of file cacert.pem
[curl] curl.cainfo="C:/xampp/php/cacert.pem"
#Matt is right, but I would add that curl.cainfo is a PHP_INI_SYSTEM directive so you must set it in php.ini...using the ini_set function in a script will always return false as I found out after too many minutes of head banging
You could create a wrapper function which sets the option and use php.ini's auto_prepend_file to load the file it's defined in, but your code would have to be changed to use this wrapper function instead.
Example:
function my_curl_init($url=null) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CAINFO, getcwd().'/cert/ca.crt');
return $ch;
}
I am using wampserver to test & run wordpress code in my local computer. In order to run pthread, I have followed the following steps:
1) I got the pthread zip file from http://windows.php.net/downloads/pecl/releases/pthreads/0.44/
(My machine has php 5.3.13 and downloaded the php_pthreads-0.44-5.3-ts-vc9-x86.zip file from the above link).
2) Extracted the zip file. Moved the php_pthreads.dll to the C:\wamp\bin\php\php5.3.13\ext directory.
3) Moved pthreadVC2.dll to the C:\wamp\bin\php\php5.3.13 directory.
4) Then Opened C:\wamp\bin\php\php5.3.13\php.ini and added the code extension=php_pthreads.dll at the begining of the file.
But when I try to run the following code:
<?php
class My extends Thread {
public function run() {
printf("%s is Thread #%lu\n", __CLASS__, $this->getThreadId());
}
}
$my = new My();
$my->start();
?>
It gives me the following error:
Fatal error: Class 'Thread' not found in C:\wamp\www\wp-admin\includes\post.php on line 2
Can you please tell me how to install pthreads in my computer to use with php? and do I have to install any other software?
I've noticed that wampserver has php.ini in two separate places. One place is in the /wamp/bin/php/php5... directory, and the other place is in the /wamp/bin/apache/apache.../bin directory (where "..." represents version numbers). The two files need to be identical, because apparently both are loaded at different times by the overall wampserver boot-up procedure.
(Note I only discovered this recently, and may be well "behind the curve" of doing fancy things with wampserver --maybe everyone else has been dealing with both files for a long time. So I don't know if this simple thing will fix your problem; I came here looking for info, myself, regarding doing some multi-threading stuff. :)
One other thing. According to this page: www.php.net/manual/en/pthreads.requirements.php
PHP has to be compiled with "--enable-zts" in order for pthreads stuff to work. I have not been able to find any evidence that the PHP part of wampserver was compiled that way.
(months later)
Having decided I didn't really immediately need to do any threading stuff, I went on to do other things, until the need actually arose. I now can say that the version of PHP compiled into WampServer does support the "pthread" extension, although some set-up work is needed, first. The instructions I saw mentioned putting a couple of .dll files (after a download and unZip) into certain places, but that didn't work for me. Copying them to the \Windows\System32 directory did work. (Putting them into the \apache...\bin directory also works; there are some other php .dll files in there.)
After that, much like what you did, it is necessary to define a "class" that extends the "Thread" class, in order to actually do something in another thread. The "run()" function in the Thread class is "abstract", and needs to be "realized" as an actual function in the extended class. Then the "new" operator can create an "instance", an object of that specified class, for actual use. Here's the class that I needed:
//Purpose: Use another thread to run the code in another php file, after a delay
class xT extends Thread
{ var $fil, $tim;
function savWhatWhen($f="", $t=0)
{ $this->fil = $f; //save What, file to process
$this->tim = $t; //save When, delay before processing file
return;
}
function run()
{ ini_set('max_execution_time', 600); //600 seconds = 10 minutes
sleep($this->tim); //do a delay; beware of max-exec-time!
include($this->fil); //load file-to-process, and process it
return;
} }
That "savWhatWhen()" function was created specifically for this extension of the basic Thread class. Here's some code for using that class:
$TH = new xT(); //prepare a separate Thread
$TH->savWhatWhen("d:/wamp/myscripts/test.php", 45);//file-name and delay time
$TH->start(); //after delay, process file
//the code that does this can terminate, while OTHER thread is doing a delay
Note for anyone copying this code, you might need to make sure your "open_basedir" setting in the php.ini allows access to the specified file.
More months later: With lots of things being worked on, I haven't put a lot of time into using my pthread object. I did encounter a peculiarity that makes me wonder about whether or not I can actually use pthreads the way I had hoped. Here is what I have observed:
1. An initial php file is called by AJAX, to do something.
2. The PHP processor on the Web Server does that thing.
3. Various data is supposed to be echoed to the browser.
4. The initial php file calls for the creation of another thread, and terminates.
5. The browser does not yet receive the echoed data!
6. The PHP processor on the Web Server does the work delegated to the second thread.
7. When the second thread terminates, NOW the browser receives the echoed data!
At this writing I'm thinking I missed something. Perhaps I need to do some forceful "flush" stuff when the first thread ends, so that the browser can receive the echoed data and the user can do things while the PHP processor on the server is also doing things.
Check for extension_dir = "ext" in you php.ini file. Make sure it points to the folder where your extensions reside and make sure it's not commented (it has a semicolon ; in front of it)
You have to add a require_once() with the path of the Thread class before extending it (if your framework don't use an autoload class system)
I've encountered the same problem, in my case placing the pthreadVC2.dll in
..wamp\bin\apache\Apache2.4.4\bin
(instead of ..\wamp\bin\php\php5.4.16 as the guide in php.net instructs) solved the problem
Wamp server has a separate php.ini config file for the browser and for the cli.
To use the pthreads module in the browser with WAMP Server you need to copy the "pthreadVC2.dll" into the apache "bin" directory also.
You should now have he "pthreadVC2.dll" in both of these folders (if installed in default location):
C:\wamp\bin\php\php[x.x.xx]\bin
C:\wamp\bin\apache\apache[x.x.x]\bin
You will also need to update the php.ini file within the php bin directory AND the apache bin directory to include:
extension=php_pthreads.dll
This now means you can use pthreads in the browser and in the cli with wamp server
After encountering the same problem, I noticed that I have installed the wrong Pthread version (3.1.6 : requires PHP7+) which wasn't compatible with my PHP version (5.5.12). Solved the problem with Pthread version 0.0.44. An earlier version should probably work well.
Here is the download page for Pthread and the installation page. Be careful about the both php.ini location as mentioned above (Apache folder=for Browser, PHP folder=CLI).
I recently upgraded from php4 to php5 and with it came the notice that all my remote php file access no longer worked. I've been doing quite a bit of research into this and I dont seem to have a clear answer as to what is the correct way to include remote urls in php5.
The first example is to include the file this way
<?php
$data = file_get_contents("http://example.com/example.inc.php",0);
echo $data;
?>
The 2nd is this way
<?php
$ch = curl_init("http://example.com/example.inc.php");
curl_exec($ch);
curl_close($ch);
?>
and 3rd is to set in my php.ini file
allow_url_include = On
allow_url_fopen = On
and use the good old
<?php include_once('http://example.com/example.inc.php');?>
I want to do this right and secure.
All solutions are correct and there is no real difference in safety AFAIK.
I think the difference can be summed up like this:
The ini-settings provide the behaviour as known from prior versions. The reason why they are disabled by default is the security thread, but that is equal to all three solutions. Including remote files is a security problem, regardless of whether you control the rmeote site or not.
file_get_contents() and the curl extension creates some overhead, since you have to buffer the content, but for php include files that is more a cosmetic thing. Their usage is slightly more complex when reading through a script. But the buffering also adds benefits: you might create a local cache for example or a checksum towards a basic plausibility check. Also a syntax check prior to execution is possible thus preventing the crash of your calling script.
Curl is provided as a php extension. So the curl solution only works when the extension is installed, but it offers a much higher grade of freedom, much more options. If you don't require those stay with the builtin functions.
Well,
First method => Is correct and you shouldnt worry using it.
Second method= > Is correct, but curl extension should be enabled
Third method => Is correct, but using this option is not recommended because enabling allow_url_include likely makes your site vulnerable. For more detail see http://en.wikipedia.org/wiki/Include_vulnerability and this link http://wiki.dreamhost.com/Allow_url_include
I am writing a class that detects whether cURL is available, does one thing if it is, and another if it isn't. I therefore need to know how to disable cURL temporarily to test this class. I do not want to change the PHP INI file. Any ideas much appreciated.
Just wondering, Im writing an alternative for if cURL is unavailble, how likely is this? Am I wasting my time. Is cURL usually available?
Curl is enabled / disabled in your php.ini. You can't enable and disable it any other way.
Open php.ini find the below and put a semi colon before it to comment it out:
extension=php_curl.dll
AFAIK there is no way to do this at run time, because modules are loaded during PHP startup, before any of you code is executed. The only way to do it is by disabling (or rather, not enabling) an extension in php.ini. You probably can't even do that with cURL, as it will probably be compiled in, not dynamically loaded.
Having said that - why not just change the check to test your "if not available" code - presumably you have a block something like this:
if (curl_exists()) { //obviously there is no such function, but you must have some condition that determines this
// Do stuff using curl
} else {
// Do something horrible
}
well, just change it to this temporarily:
if (!curl_exists()) {
// etc etc
I think the best option is to change your detection script to allow disabling it with a manual configuration.
You cannot disable function on the fly. You need to change php.ini for that.
http://www.php.net/manual/en/function.dl.php
dl — Loads a PHP extension at runtime
bool dl ( string $library )
Loads the PHP extension given by the parameter library.
Use extension_loaded() to test whether a given extension is already available or not. This works on both built-in extensions and dynamically loaded ones (either through php.ini or dl()).
Warning:
This function has been removed from some SAPI's in PHP 5.3.
<?php
// Example loading an extension based on OS
if (!extension_loaded('sqlite')) {
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
dl('php_sqlite.dll');
} else {
dl('sqlite.so');
}
}
//this deals with sqlite but would be easy to figure out how to use it for cURL :)
?>
So you can comment out the loading of cURL extension in php.ini and then "dynamically load" it when needed.
HTH
probably the easiest way is by open file curl.ini, Im use ubuntu 12.04 and file located at
/etc/php5/apache2/conf.d/curl.ini
leave a comment by adding semicolon before extension=curl.so
You can see the location of curl.ini through phpinfo ();
dont forget to restart the Apache
sudo service apache2 restart
Curl is available as long its extension is loaded (which is mostly by default).
You can check what curl extension provides by the following command:
php --re curl
which gives you list of functions, classes and its methods.
To temporary disable curl extension, you can run PHP with -n to simply ignore your php.ini, for example:
$ php -n -r "print_r(curl_version());"
Fatal error: Call to undefined function curl_version() in Command line code on line 1
Here is working example:
$ php -r "print_r(curl_version());"
Array
(
[version_number] => 463623
...
We are using shared hosting and the follow features are disabled.
file_uploads = Off
allow_url_fopen = Off
allow_url_include = Off
We are unable to change hosting and need to figure out some workarounds. The hosting co is also not able/willing to enable these features.
For example:
We are calling 1 server from another in order to get content. So we do an include but since URL file include is disabled we are not sure what options we have to get the content on that second server and store it there using some kind of cache.
We control the content server fully (dedicated) so we can do whatever necessary just not sure if there is some easy solution to the problem.
Since you're looking to retrieve remote content the easiest way will be to write the functionality to fetch the content yourself with something like curl (php.net/curl)
Have you tried something like this:
http://www.humanumbrella.com/2007/12/08/how-to-download-a-remote-file-in-php-and-then-save-it/
It depends on how locked down the server is. The given examples (using curl functions or fsockopen) should not be hampered by the restrictions you mentioned.
You can solve your problem like this
a) Create mechanism in dedicated server to fetch any file (plus some kind of key based authentication and restrictions on paths where files can be fetched from)
eg: A url that says get_file?path=/path/to/file&key=security_key
b) Write a function to fetch this as if from a local file
function fetch_file($path) {
$ch = curl_init("http://www.example.com/get_file?path=$path&key=security_key");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
Then you can eval the returned string and that would be like including the file
eval fetch_file($path);
Another solution to write to the server if php file upload is prevented is to ftp the file on to your server and include the file.