PHP Considers my absolute path a relative one - php

Currently I have PHP 7.2 installed and I was trying to get spatie/image-optimizer to work but somehow it considers my literal paths as non existent ones. If I give it the following path:
/data/www/MY DOMAIN/images/thumbnails/700/615/detailed/1/83-221-343-V01.jpg
It will output the following:
2018/07/13 14:44:26 [error] 18931#18931: *3749 FastCGI sent in stderr:
"PHP message: PHP Fatal error: Uncaught InvalidArgumentException:
/data/www/MY DOMAIN/images/thumbnails/700/615/detailed/1/83-221-343-V01.jpg
does not exist in
/data/www/MY DOMAIN/app/addons/theme/lib/vendor/spatie/image-optimizer/src/Image.php:14
But if I check the directory I can confirm that the file is there with the correct permissions.
Any ideas?

I just looked at the Image class on Github. Here's where the exception is thrown.
public function __construct(string $pathToImage)
{
if (! file_exists($pathToImage)) {
throw new InvalidArgumentException("`{$pathToImage}` does not exist");
}
$this->pathToImage = $pathToImage;
}
A good way of checking you have it properly set is to use realpath()
Realpath creates absolute paths from relative ones, returning false if the path doesn't exist.
$path = __DIR__ .'/../../something'; // (imagine __DIR__ is /some/random/path to begin with)
echo $path; // outputs /some/something
You can also check in your terminal simply by typing:
ls /path/to/image.jpg
If it lists, it does indeed exist and shouldn't throw an error.

Switch to the user your php is running as and try to access the file. It could be that you are missing the execute permissions on one of the folders on the way to the file.

Related

Facing issue while performing file reading operations in php

I am new to php . Currently as part of Migration activity we copied the existing php application to a new infrastructure where we are facing a strange issue.
Problem Statement:
From the php application,not able to read any file and it is not throwing any errors also. I used the following libraries and got the same behavior:
file_get_contents (This is the existing mechanism and I should use this one in the new infrastructure also)
Below two, checked to triage the issue:
readfile
fopen (tried with fopen just to see whether able to open like fopen($file, "r") or die( ),but this is also going to die condition
Issue Triaging
Made the below sample.php and make it available in my current server configuration. This is available by accessing through url (for e.g. https://myapplicationdomain/myapplication/sample.php). This php component is reading an input.txt which is in the same directory (actually this is the simulation of our problem)
<?php
ini_set('display_errors', 1); // show errors
error_reporting(-1);
//set your own error handler before the call
set_error_handler(function ($err_severity, $err_msg, $err_file, $err_line, array $err_context)
{
throw new ErrorException( $err_msg, 0, $err_severity, $err_file, $err_line );
}, E_WARNING);
echo "fopen url is";
var_dump(ini_get('allow_url_fopen'));
try{
$file ='input.txt';
if(is_readable($file)) {
echo "$file is readable \n"
} else {
echo "$file is not readable \n";
}
if(file_exists($file))
{
$homepage = file_get_contents($file);
var_dump($homepage);
echo "content is $homepage \n";
}else{
echo "file is not present \n";
}
}catch (Exception $e) {echo 'Error Caught $e';}
?>
Apache server is running using apache user and this user is having permission in the files and parent directories,
Following are the observations we got during triaging this:
When accessing through url for e.g. https://myapplicationdomain/myapplication/sample.php (i.e. through apache server).
a. functions is_readable & file_exists are returning true.
b. file_get_contents is returning blank and when I did var_dump, it is returning 'Null'
c. Confirmed the value of allow_url_fopen and it is returning 1 which is true
d. No errors are getting logged in this case.
e. Changed the permission of the 'input.txt' to see the permission behaviour. In that case,proper error got displayed in is_readable it self.So through this way ruled out the possibility of permission issue and also confirmed the error handler implementation is working fine.
f. Changed the location of input.txt to outside folders . ie. home/apache_user/ or root directory. Still file read operations are failing.
Able to run the same php code independently. i.e php sample.php .In this case,it is working as expected and all file reading operations are working fine.
3.Checked all the below php.ini configurations (removed all the values in disabled functions for testing)
a. open_basedir => no value
b. disabled_functions => no value
c. allow_url_fopen => true
Checked all the posts ,but not getting any idea how to proceed further. Following are version we are using: PHP 7.3.5 , CodeIgnitor framework and also configured php-fpm.
As per my understanding php library which apache was referring had some issues. Since it is a migration project and it is working fine in the current environment,copied the existing php folder (which was inside apache) and fpm binaries and configurations from the working environment to the new environment.Still not got any idea on exact root cause (as only read scenario was failing),but this got worked

PHPSECLIB call to undefined function crypt_random_string()

I'm trying to upload a file to sftp server using phpseclib library. Here's the code I've written
set_include_path(get_include_path() . PATH_SEPARATOR . 'phpseclib0.3.5');
$fileName = "sImg3.jpeg";
$fileData = file_get_contents($fileName);
$b64Data = base64_encode($fileData);
// upload the file to ftp server
include('Net/SFTP.php');
include_once('include/config.php'); // contains sftp connection details
$sftp = new Net_SFTP($ftpHost);
if (!$sftp->login($ftpUser, $ftpPasswd))
{
die("Failed to connect to SFTP server");
}
else
{
$sftp->put($filename,$b64Data);
echo "Uploaded the file (".$filename.")\n";
}
When I try to run this, I'm getting:
PHP Fatal error: Call to undefined function crypt_random_string() in
/var/www/phpseclib0.3.5/Net/SSH2.php on line 1014
I've installed php5-mcrypt and phpseclib. Do I need to install any other dependencies for phpseclib? Please let me know.
Thanks much in advance,
Regards,
Sudheer
crypt_string_random is defined in Crypt/Random.php:
https://github.com/phpseclib/phpseclib/blob/0.3.5/phpseclib/Crypt/Random.php
But then again Net_SSH2 auto-includes Crypt/Random.php:
https://github.com/phpseclib/phpseclib/blob/0.3.5/phpseclib/Net/SSH2.php#L749
And Net_SFTP extends Net_SSH2:
https://github.com/phpseclib/phpseclib/blob/0.3.5/phpseclib/Net/SFTP.php#L253
And Net_SSH2 does a require_once so if anything you should be getting some sort of "file not found" error, if you're getting an error at all, not a "function not defined" error..
The problem is caused by how PHP handles nested include statements and relative paths. If you look at the current phpseclib programming, at least 'some' of the includes still use include() instead of require_once() which silently fail - which is why you don't see the errors about failing includes.
It all comes down to how PHP resolves relative pathing of nested includes - using the starting location of the parent script or the starting location of the current/child script. More info on the conundrum of PHP nested includes with relative pathing here:
php nested include behavior
When I ran into this problem myself, I worked around it by promoting /phpseclib out of it's own subfolder and into my existing /includes folder. Then I only ever include phpseclib files from within php scripts in my /includes folder so that the relative paths in phpseclib's nested include statements will work.

Mounting a folder in a phar doesn't work

I've created a phar of a Symfony2 web application, but I'm having some troubles with the cache-folders.
I found out that I could mount an external file/folder into a phar. That would fix my issue, but I can't get the example on the PHP site working.
I have a phar which contains an index.php:
<?php
$configuration = simplexml_load_string(file_get_contents(
Phar::running(false) . '/config.xml'));
?>
Then I include the .phar with the following code:
<?php
// first set up the association between the abstract config.xml
// and the actual one on disk
Phar::mount('phar://config.xml', '/var/www/$projectname/config.xml');
// now run the application
include 'phar-archive.phar';
?>
All files exists, but I get the following error:
PHP Fatal error: Uncaught exception 'PharException' with message 'config.xml is not a phar archive, cannot mount' in /var/www/$projectname/index.php:3
I already tried relative/absolute paths, changing permissions but can't get this to work. Additionally a working example of how I could mount a folder into a phar would be great !
First check that variable $projectname exist in this place (just run echo $projectname; before Phar::mount). If all ok, then change
Phar::mount('phar://config.xml', '/var/www/$projectname/config.xml');
to
Phar::mount('phar://config.xml', "/var/www/{$projectname}/config.xml");
It seems that variable $projectname not converted to its value because you used single quotes.

"current directory" notation not working

I was taught that it's good practice to specify the directory of a file you're linking to, even when the file is in the current directory. So, for example, use "./constants.inc.php" as opposed to "constants.inc.php". This has generally worked fine for me, except in one particular spot in my code I get the following PHP error when I use the ./ notation:
Warning: require(./constants.inc.php) [function.require]: failed to open stream: No such file or directory in C:\xampp\htdocs\widget_corp\includes\functions.inc.php on line 4
Fatal error: require() [function.require]: Failed opening required './constants.inc.php' (include_path='.;C:\xampp\php\PEAR;C:\xampp\htdocs\websites\mathverse\includes') in C:\xampp\htdocs\widget_corp\includes\functions.inc.php on line 4
Writing "./constants.inc.php" gives this error, but "constants.inc.php" doesn't (PHP seems to find the file just fine). Can someone tell me why the ./ notation doesn't work in this particular case? Perhaps it's something very simple I'm missing?
To give a bit more context (if necessary), the error is in the function below (line 2), which is in my PHP functions file (called functions.inc.php) which is inside an includes directory. The constant.inc.php file is also inside the includes directory.
Thank you.
function connect_to_db() {
require("./constants.inc.php");
$connection_id = mysql_connect(DB_SERVER, DB_USER, DB_PASS);
if (!$connection_id) {
die("Database connection failed: " . mysql_error());
}
$db_selection_was_successful = mysql_select_db(DB_NAME, $connection_id);
if (!$db_selection_was_successful) {
die("Database selection failed: " . mysql_error());
}
}
Writing "./constants.inc.php" gives this error, but "constants.inc.php" doesn't (PHP seems to find the file just fine). Can someone tell me why the ./ notation doesn't work in this particular case? Perhaps it's something very simple I'm missing?
The only explanation I have is that PHP seems to be finding the constants.inc.php file in one of the directories in the include path - most likely C:\xampp\htdocs\websites\mathverse\includes.
even with or without ./ PHP will be searching for same file (in case of ./, it won't search in include_path) , and this means that constats.inc.php DOES NOT exist.
Try this one
require(dirname(__FILE__)."/../constants.inc.php");
Create the following heirachy:
index.php // echo 'I am in the top directory';
folder1/
index.php // echo 'I am in folder 1';
folder2/
index.php // 'echo I am in foler' 2
on your top level index.php require folder1/index.php. From that require 'folder2/index.php';
This works no problem. However add a ./ before the folder2/index.php and you will get an error. It seems as once you specify which folder you want by using the ., it has to be relative to the current working directory. But if left open, the path will be checked in the calling scripts own directory too.
From the manual:
Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include will finally check in the calling script's own directory and the current working directory before failing. The include construct will emit a warning if it cannot find a file; this is different behavior from require, which will emit a fatal error.

PHP PEAR Validate Package - Fatal error: Class 'Validate' not found

This is the error I am receiving:
Fatal error: Class 'Validate' not found in C:\xampp\htdocs\final_project\validate.php on line 5
And here is my PHP code:
<?php
require_once 'Validate.php';
foreach($_POST as $name => $value)
{
$valid = Validate::string($value);
}
?>
I do not understand what I am missing. I installed --alldeps for the validate package, and the PEAR include path is also correct. Validate_CA is not giving me any errors, but it is not properly validating either.
PHP parses the include_path in order of precedence. This means that when a relative path is passed to require(), include(), fopen(), file(), readfile() or file_get_contents(), PHP will start looking in the first directory. If the file is found, it includes it. If not, it will continue to the next and repeats the process.
Consider the following include path:
include_path = ".:/php/includes:/php/pear"
and the following PHP script:
<?php
require('MyFile.php');
PHP will look for MyFile.php in the following order:
./MyFile.php (Current Directory)
/php/includes/MyFile.php
/php/pear/MyFile.php
The reason why you cannot load Validate.php is you already have a file called validate.php (remember, paths are not case-sensitive on Windows, but are on UNIX) in your current directory. Therefore, PHP includes your file instead of the file corresponding to PEAR::Validate since yours is found before PEAR's in the include_path order of precedence.
Simply renaming your file to something else than validate.php should fix your problem. If it still doesn't work, try echoing the return value of get_include_path() to make sure it really is set right.

Categories