How can I get the path of the PHP binary from PHP? - php

How can I get the binary path of php from PHP?
I saw it in phpinfo(), but I need another method that gets it in Linux and Windows systems.

You can use:
$_SERVER['_']
Also, the predefined constant PHP_BINDIR gives the directory where the PHP executable is found.
Sample on CodePad and Ideone.
It looks like, for security reasons, $_SERVER values are not exposed.

Linux Only
Use the "which" command to find php.
$phpPath = exec("which php");
Note this does not guarantee the same php executable that your web server may be using, but rather the first instance that was found while looking through the paths.

A method using environment variables, assuming the php executable is in the system path.
function getPHPExecutableFromPath() {
$paths = explode(PATH_SEPARATOR, getenv('PATH'));
foreach ($paths as $path) {
// We need this for XAMPP (Windows)
if (strstr($path, 'php.exe') && isset($_SERVER["WINDIR"]) && file_exists($path) && is_file($path)) {
return $path;
}
else {
$php_executable = $path . DIRECTORY_SEPARATOR . "php" . (isset($_SERVER["WINDIR"]) ? ".exe" : "");
if (file_exists($php_executable) && is_file($php_executable)) {
return $php_executable;
}
}
}
return FALSE; // Not found
}

Maybe the best solution is in the Symfony process component:
PhpExecutableFinder.php and ExecutableFinder.php. In use:
<?php
use Symfony\Component\Process\PhpExecutableFinder;
$phpFinder = new PhpExecutableFinder;
if (!$phpPath = $phpFinder->find()) {
throw new \Exception('The php executable could not be found, add it to your PATH environment variable and try again');
}
return $phpPath;

In Windows, using WAMP, you can use the ini variable - extension_dir - as it is placed in the PHP folder.
Like this:
echo str_replace('ext/', 'php.exe', ini_get('extension_dir'));

Normally, in a simple default PHP installation under Windows, the php.ini file is located and loaded from the same directory of the PHP binary.
To simplify, Windows users:
echo dirname(php_ini_loaded_file()).DIRECTORY_SEPARATOR.'php.exe';
VoilĂ !
Of course, if you are using multiple .ini files, it may not work if the files are not into the same PHP binary directory. BTW, this may solve to most of cases. Windows developers running PHP from local development environment.

As of PHP 5.4 you can simply use the PHP_BINARY reserved constant.

It's very easy!
var_dump(getenv('PHPBIN'));
But it works only on Windows, so we should use this answer.
How did I get this? I just typed echo echo phpinfo(); and searched the php path there. Just see here:
Then I just getting it here: php getenv and ... you see the result.

For Windows and XAMPP:
$php = getenv('PHPRC') . '/php.exe';
if(is_file($expected)){
return $php;
}

Related

PHP 8.1.2 realpath returning false

I am currently upgrading my PHP website from 7.4 to 8.1.2 but I'm having an issue with 'realpath'. No matter what directory I put in the variable '$install_folder' just shows as false. It's bizarre as I tested this on my PHP 7.4 website and the code works as it should.
$install_folder = realpath(__DIR__ . '/../../../');
I have tried to cheese the fix by:
$dir = __DIR__;
$install_folder = realpath($dir . '/../../../');
Any suggestions would be highly appreciated!
Is the php cli interpreter installed on your system? On Debian/Ubuntu based systems this is the phpX-cli package.
IF the cli package is installed, I'd want to see the output of a test script that might shed some light on things.
#/path/to/php8
$dir = __DIR__;
echo $dir;
$install_folder = realpath($dir);
echo $install_folder;
Run this script as a regular user, and then as the user running the web site.

How to define $_SERVER['DOCUMENT_ROOT']

I am trying to install a PHP application on a Linux running Apache2 and PHP5.
I noticed that, whenever I try to access the application (for example, hitting the index.php file), the browser returns a blank page. Running a phpinfo() works fine though.
Through testing, I have realized that the problem lies in the code of the applicatio, which has lost of lines like this one:
require_once($_SERVER['DOCUMENT_ROOT'] . '/202-config/functions.php');
If I change this to require_once('./202-config/functions.php');, then the application runs ok (at least that part of the application.
If I run a print_r($_SERVER), DOCUMENT_ROOT appears empty.
My question for you guys is: as I dont want to go through all the code in this application and replace these require_once statements, is there a way to define the value of DOCUMENT_ROOT?
Thanks.
From the docs:
The entries in this array are created by the web server. There is no guarantee that every web server will provide any of these;
Also if you run script from command line it might not be set.
Workaround is to set explicitly:
if (!isset($_SERVER['DOCUMENT_ROOT']) || empty($_SERVER['DOCUMENT_ROOT']))
$_SERVER['DOCUMENT_ROOT'] = __DIR__; //or dirname(__FILE__) for older php verstions
Note: You use $_SERVER['DOCUMENT_ROOT'] to include scripts. So it's better idea to rely on constants __DIR__ and __FILE__ rather than $_SERVER.
Do you have set the DocumentRoot "/var/www" in your Apache-Virtualhost-Config? In CLI this field is empty. In that case you can set this value manually:
if ($_SERVER['DOCUMENT_ROOT'] == '') {
$_SERVER['DOCUMENT_ROOT'] = __DIR__;
}
or for PHP < 5.2
if ($_SERVER['DOCUMENT_ROOT'] == '') {
$_SERVER['DOCUMENT_ROOT'] = dirname(__FILE__);
}
You also could do something like this:
if (empty($_SERVER['DOCUMENT_ROOT'])) {
$_SERVER['DOCUMENT_ROOT'] = './';
}
But this is not a nice way

Check if PHP is installed on Apache or IIS Server?

Is there a way to check if PHP is installed on an Apache or IIS server within the PHP environment itself?
If so, how?
create a file (say info.php) with the following content on an accessible path and try to browse it:
<?php
phpinfo();
?>
#Alfabravo is correct: don't forget to delete the file from the server after using it!
Create a PHP script called php.php with the content:
<?php
phpinfo();
?>
and run it from your browser. Or from command line, run:
php -v
I don't know with what PHP version it became available, but try this:
if( strpos( $_SERVER['SERVER_SOFTWARE'], 'Apache') !== false)
echo 'Have Apache';
else
echo 'Have some other server';
The virtually most definitive answer possible (there are other similar possibilities) is:
function on_iis() {
$sSoftware = strtolower( $_SERVER["SERVER_SOFTWARE"] );
if ( strpos($sSoftware, "microsoft-iis") !== false )
return true;
else
return false;
}
Now, just use on_iis() whenever you want to know.
You can also find out via the $_SERVER['DOCUMENT_ROOT'], sort of:
Read http://www.helicron.net/php/
(Basically, according to the article, Apache sets the document root with a valid variable, and IIS does not).

Unpack/extract zip file with PHP without relying on any extension

Is there any way to unpack or extract a zip file with PHP that does not rely on any installed extension? Has anyone written a class or something that can handle it?
Alternatively, is there a solution that uses an extension that is relatively commonly installed on most servers?
I need this to work on as many different servers that I have no control over as possible.
Thanks for any help!
Check this lib it helps to solve same problem
require_once('pclzip.lib.php');
$archive = new PclZip(dirname(__FILE__).'/Archive.zip');
if ($archive->extract(PCLZIP_OPT_PATH, dirname(__FILE__).'/extract') == 0) {
echo "\n error while extract";
} else {
echo "\n extract ok";
}
Well, it looks like most of them require php.ini settings, which you may be able to override in your script:
http://www.w3schools.com/php/php_ref_zip.asp
http://devzone.zend.com/article/2105
and here is how to edit the php.ini file without direct access:
http://www.whenpenguinsattack.com/2006/01/20/how-to-override-phpini/

Can't get SFTP to work in PHP

I am writing a simple SFTP client in PHP because we have the need to programatically retrieve files via n remote servers. I am using the PECL SSH2 extension.
I have run up against a road block, though. The documentation on php.net suggests that you can do this:
$stream = fopen("ssh2.sftp://$sftp/path/to/file", 'r');
However, I have an ls method that attempts to something similar
public function ls($dir)
{
$rd = "ssh2.sftp://{$this->sftp}/$dir";
$handle = opendir($rd);
if (!is_resource($handle)) {
throw new SFTPException("Could not open directory.");
}
while (false !== ($file = readdir($handle))) {
if (substr($file, 0, 1) != '.'){
print $file . "\n";
}
}
closedir($handle);
}
I get the following error:
PHP Warning: opendir(): Unable to open ssh2.sftp://Resource id #5/outgoing on remote host
This makes perfect sense because that's what happens when you cast a resource to string. Is the documentation wrong? I tried replacing the resource with host, username, and host and that didn't work either. I know the path is correct because I can run SFTP from the command line and it works fine.
Has anyone else tried to use the SSH2 extenstion with SFTP? Am I missing something obvious here?
UPDATE:
I setup sftp on another machine in-house and it works just fine. So, there must be something about the server I am trying to connect to that isn't working.
When connecting to a SFTP server and you need to connect to the root folder (for instance for reading the content of the folder) you would still get the error when using just "/" as the path.
The solution that I found was to use the path "/./", that's a valid path that references to the root folder. This is useful when the user you are logging with has access only to its own root folder and no full path is available.
So the request to the server when trying to read the contents of the root folder should be something like this:
$rd = "ssh2.sftp://{$this->sftp}/./";
For php versions > 5.6.27 use intval()
$sftpConnection = ssh2_connect($host);
$sftp = ssh2_sftp($sftpConnection);
$fp = fopen("ssh2.sftp://" . intval($sftp) . $remoteFile, "r");
https://bugs.php.net/bug.php?id=73597
I'm having a similar issue. I assume you are doing something similar to this:
$dir = "ssh2.sftp://{$sftp}{$remote_dir}";
$handle = opendir($dir);
When $remote_dir is the full path from root then open_dir works. If $remote_dir is just '/' or '', then I get the 'unable to open' error as you did.
In my case, it seems ssh connects at the root folder instead of the 'home' directory as ftp does. You mentioned that it worked on a different server, so I wonder if it is just a config issue.
the most easiest way to get SFTP working within PHP (even on windows) without installing any extension etc is PHPSECLIB: http://phpseclib.sourceforge.net/ . The SSH stuff is completely implemented in a PHP class.
You use is like this:
<?php
include('Net/SFTP.php');
$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
exit('Login Failed');
}
echo $sftp->pwd();
?>
The documentation on that page contains an error. Take a look at the example here instead: http://php.net/ssh2_sftp - what you actually need to do is to open a special SFTP resource using ssh2_sftp() prior to using it with fopen(). And yes, it looks just like that, e.g. "Resource #24" when converted to string... a bit weird but apparently it works.
Another caveat is that SFTP starts in the root directory rather than the home directory of the remote user, so your remote path in the URI should always be an absolute one.
I just had the same issue, but I could figure out the problem.
On my case, when connecting to the server, I was going to the root of the account, and due to server configs I wasn't able to write there.
I have connected to the account using a fireFTP, and so I could see where the root of the account was...it was the root of the server.
I had to include the whole path until the folder where I am allowed to write, and so I could solve the issue.
So, my advice is to get the path using a graphic interface (I have used fireFTP), and add the whole path to your code.
$pathFromAccountRootFolderToMyDestinationFolder = '/Account/Root/Folder/To/My/Folder';
$stream = fopen("ssh2.sftp://".$sftp."/".$pathFromAccountRootFolderToMyDestinationFolder."/myFile.ext", 'r');
Hope this will help you and other people with the same issue!
Cheers!
I recently tried to get SFTP on PHP working and found that phpseclib was a lot easier to use:
http://phpseclib.sourceforge.net/
If you have the luxury of not being on a shared host and can install whatever extensions you want to maybe the PECL extension would be better but not all of us are so lucky. Plus, phpseclib's API looks a bit more intuitive, being OOP and all.
My issue was, that I was connecting in function and returning string URL with resource inside. Unfortunatelly resource is than created in function context and garbage collector is disconnecting resource on function end. Solution: return resource by reference and unset it manually in more complex context.
Solved my issue by enabling sftp support on the (Powershell) server
This is a bug in the ssh2 package that I found years ago and posted a patch to php.net. It fixes this issue but requires a rebuild of the ssh2 pecl package. You can read more here: https://bugs.php.net/bug.php?id=69981. I included a patch there to the ssh2_fopen_wrappers.c file in the package to fix the issue. Here is a comment I included:
Here is a line of code from ssh2_fopen_wrappers.c that causes this bug: (comment included)
/*
Find resource->path in the path string, then copy the entire string from the original path.
This includes ?query#fragment in the path string
*/
resource->path = estrdup(strstr(path, resource->path));
This line of code -- and therefore this bug -- was introduced as a fix for bug #59794. That line of code is attempting to get a string containing the part, query and fragment from the path variable.
Consider this value for the path variable:
ssh2.sftp://Resource id #5/topdir?a=something#heading1
When resource->path is "/topdir", the result is that "/topdir?a=something#heading1" gets assigned to resource->path just like the comment says.
Now consider the case when resource->path is "/". After the line of code is executed, resource->path becomes "//Resource id#5/topdir#heading1". This is clearly not what you want. Here's a line of code that does:
resource->path = estrdup( strstr( strstr( path, "//" ) + 2, "/" ) );
You may also need to apply the patch for bug # 73597 which removes "Resource id #" from the path string before calling php_url_parse().

Categories