I have this short script to detect the user usage environment and try to normalize the root path:
Located in C:\xampp\htdocs\dev\t2\Last-Hammer\configs\const\loader.php
$env= '';
if (php_sapi_name() == 'cli') {
$env= 'cli';
if (!isset($_SERVER['PWD'])) {
$path = dirname(__DIR__).'\\';
} else {
$path = dirname($_SERVER['PWD']);
}
} else {
$env= 'web';
$path = $_SERVER['DOCUMENT_ROOT'];
}
echo $path;
echo PHP_EOL;
echo $env;
file_get_contents($path.'configs/const/client.xml')
i use it from 2 diferent files: index.php that wor well in root folder but trying to use it from a sub-directory like this /dev/cron.php
cron.php content:
$path = (!isset($_SERVER["PWD"]) ? dirname(__DIR__).'\\' : dirname($_SERVER["PWD"]));
require_once $path.'/configs/const/loader.php';
i get this output
//from Web environment
C:/xampp/htdocs/dev/t2/Last-Hammer/
web
and
//from CLI environment
C:\xampp\htdocs\dev\t2\Last-Hammer
cli
the problem is that this work correctly from Web environment but not work correctly in CLI, when i try to execute like: php cron.php code try to make a file_get_contents... like this using cli get this error:
PHP Warning: file_get_contents(C:\xampp\htdocs\dev\t2\Last-Hammer\configs\configs/const/client.xml): failed to open stream: No such file or directory in C:\xampp\htdocs\dev\t2\Last-Hammer\configs\const\loader.php on line 24
Warning: file_get_contents(C:\xampp\htdocs\dev\t2\Last-Hammer\configs\configs/const/client.xml): failed to open stream: No such file or directory in C:\xampp\htdocs\dev\t2\Last-Hammer\configs\const\loader.php on line 24
what is expected is that both for CLI or WEB, the root of the project is similar to: C:/xampp/htdocs/dev/t2/Last-Hammer/ and does not change constantly in the case of CLI depending on where it is executed the php file, as root could set in CLI. regardless of where it runs.
You are lacking trailing "\" on cli case. to uniform both, you could use str_replace():
$env= '';
if (php_sapi_name() == 'cli') {
$env= 'cli';
if (!isset($_SERVER['PWD'])) {
$path = dirname(__DIR__).'\\';
} else {
$path = dirname($_SERVER['PWD']).'\\';
}
} else {
$env= 'web';
$path = $_SERVER['DOCUMENT_ROOT'];
}
$path = str_replace( '\\', '/', $path );
echo $path;
echo PHP_EOL;
echo $env;
file_get_contents($path.'configs/const/client.xml')
define in your main scripts:
define('DOCROOT', '../'); // this in your cron.php
define('DOCROOT', './'); // this in your index.php
Just use relative paths:
$path = DOCROOT;
file_get_contents($path.'configs/const/client.xml')
Related
Does PHP's built in server not make use of .htaccess? Makes sense, I suppose, as it isn't relying upon Apache(?). Anyway, is it possible to tell the server to make use of these files - can it handle URL rewrites? I have some projects in frameworks that rely upon these files.
APPLICATION_ENV=development php -S localhost:8000 -t public/
Here's the router that I use for the builtin php webserver that serves assets from the filesystem if they exist and otherwise performs a rewrite to an index.php file.
Run using:
php -S localhost:8080 router.php
router.php:
<?php
chdir(__DIR__);
$filePath = realpath(ltrim($_SERVER["REQUEST_URI"], '/'));
if ($filePath && is_dir($filePath)){
// attempt to find an index file
foreach (['index.php', 'index.html'] as $indexFile){
if ($filePath = realpath($filePath . DIRECTORY_SEPARATOR . $indexFile)){
break;
}
}
}
if ($filePath && is_file($filePath)) {
// 1. check that file is not outside of this directory for security
// 2. check for circular reference to router.php
// 3. don't serve dotfiles
if (strpos($filePath, __DIR__ . DIRECTORY_SEPARATOR) === 0 &&
$filePath != __DIR__ . DIRECTORY_SEPARATOR . 'router.php' &&
substr(basename($filePath), 0, 1) != '.'
) {
if (strtolower(substr($filePath, -4)) == '.php') {
// php file; serve through interpreter
include $filePath;
} else {
// asset file; serve from filesystem
return false;
}
} else {
// disallowed file
header("HTTP/1.1 404 Not Found");
echo "404 Not Found";
}
} else {
// rewrite to our index file
include __DIR__ . DIRECTORY_SEPARATOR . 'index.php';
}
It is not possible to handle .htaccess using PHP's built-in webserver (it is not relying on apache, it is implemented entirely in PHP's core). However, you can use router script (described here: http://php.net/manual/en/features.commandline.webserver.php).
E.g. php -S localhost -S localhost:8080 router.php
We're currently working with legacy projects and I came accross with the same problem. Based on #Caleb's answer, we managed to add a few more controls:
Route the request to an old htaccess router (url.php on the example below);
Work with query string;
Change the current directory to work with PHP includes;
Plus: naming to server.php to match Laravel's PHP Builtin router.
Just type in the cmd: php -S localhost:8888 server.php
chdir(__DIR__);
$queryString = $_SERVER['QUERY_STRING'];
$filePath = realpath(ltrim(($queryString ? $_SERVER["SCRIPT_NAME"] : $_SERVER["REQUEST_URI"]), '/'));
if ($filePath && is_dir($filePath)){
// attempt to find an index file
foreach (['index.php', 'index.html'] as $indexFile){
if ($filePath = realpath($filePath . DIRECTORY_SEPARATOR . $indexFile)){
break;
}
}
}
if ($filePath && is_file($filePath)) {
// 1. check that file is not outside (behind) of this directory for security
// 2. check for circular reference to server.php
// 3. don't serve dotfiles
if (strpos($filePath, __DIR__ . DIRECTORY_SEPARATOR) === 0
&& $filePath != __DIR__ . DIRECTORY_SEPARATOR . 'server.php'
&& substr(basename($filePath), 0, 1) != '.'
) {
if (strtolower(substr($filePath, -4)) == '.php') {
// change directory for php includes
chdir(dirname($filePath));
// php file; serve through interpreter
include $filePath;
} else {
// asset file; serve from filesystem
return false;
}
} else {
// disallowed file
header("HTTP/1.1 404 Not Found");
echo "404 Not Found";
}
} else {
// rewrite to our router file
// this portion should be customized to your needs
$_REQUEST['valor'] = ltrim($_SERVER['REQUEST_URI'], '/');
include __DIR__ . DIRECTORY_SEPARATOR . 'url.php';
}
I made a function to get the main folder path in which website is stored. In localhost it works fine.
function get_path()
{
$current=dirname(__FILE__) . '/';
$name=basename(__DIR__);
$from=array($name);
$to=array('');
$result=str_replace($from,$to,$current);
return trim($result, "/\\");
}
But in server it shows error while including files.
include(): Failed opening 'home3/home/public_html/dev/ship\model\main.php' for inclusion (include_path='.:/opt/php54/lib/php')
The file is there in that directory for sure. But its not working.
Try the following
// Define directory separator
define('DS', DIRECTORY_SEPARATOR);
function get_path()
{
$current = dirname(__FILE__) . DS;
$name = basename(__DIR__);
$from = array($name);
$to = array('');
$result = str_replace($from, $to, $current);
return $result;
}
Or you could use:
// define directory separator
define('DS', DIRECTORY_SEPARATOR);
function get_path($withSlash = true)
{
$path = realpath(dirname(__FILE__));
if ($trailingSlash) {
$path .= DS;
}
return $path;
}
You're stripping out the first slash (first character) - plus you're using \ instead of / in the path.
For the creation of paths you should use the PHP-function realpath to manage the slashes: http://php.net/realpath
I am running this code to read a directory (on Apache server):
$mydir = '/media/video/';
$root_dir = $_SERVER["DOCUMENT_ROOT"];
if(strpos($_SERVER['HTTP_HOST'], 'localhost') === false){
$dir = $root_dir . $mydir;
}else{
$dir = $mydir;
}
There have been some server configuration changes recently and now it returns this:
/home2/interact/public_html
Is there a rmore reliable way to always get corrent root path?
I need a public_html path.
// split url path on '/' slash characher and save result in $urlParts(array). check if $urlParts array contains public_html. it means /home2/interact/public_html is root.
$dirPath = dirname ( FILE );
$urlParts = explode('/', $dirPath);
if(in_array('public_html', $urlParts)) {
//do something
}
I am making a intranet customer manager in PHP. For each customer a directory is created for the shop to add files into. What my script is supposed do is if no directory exists create it, if it does exists dont create it.
What is actually happening is if the directory already exists I am getting the following error :
Warning: mkdir() [function.mkdir]: File exists in C:\server2go\server2go\htdocs\customermgr\administrator\components\com_chronoforms\form_actions\custo m_code\custom_code.php(18) : eval()'d code on line 14
So what is happening it is trying to create it anyway, even though the if statement should stop it ?, im confused on what I am doing wrong :-S .
<?php
$customerID = $_GET['cfid'];
$directory = "/customer-files/$customerID";
if(file_exists($directory) && is_dir($directory)) {
}
else {
$thisdir = getcwd();
mkdir($thisdir ."/customer-files/$customerID" , 0777); }
?>
Replace:
if(file_exists($directory) && is_dir($directory)) {
with:
$thisdir = getcwd();
if(file_exists($thisdir.$directory) && is_dir($thisdir.$directory)) {
or better:
<?php
$customerID = $_GET['cfid'];
$directory = "./customer-files/$customerID";
if(file_exists($directory) && is_dir($directory)) {
}
else {
mkdir($directory , 0777); }
?>
Just took a short look but i would try this:
$directory = $thisdir . "/customer-files/$customerID";
and remove $thisdir from mkdir();
also you should move your $thisdir before the $directory declaration
The function file_exists() does not use relative paths, where is_dir() can. So instead, use the common denominator and pass an absolute path to these functions. Additionally you can move the call to getcwd() into the $directory assignment and reuse $directory later for creating the directory.
<?php
$customerID = $_GET['cfid'];
// Get full path to directory
$directory = getcwd() . "/customer-files/$customerID";
if(file_exists($directory) && is_dir($directory)) {
// Do nothing
}
else {
// Directory doesn't exist, make it
mkdir($directory , 0777); }
}
?>
I'm trying to make a php script to connect to an afp server and get a directory listing (with each file size). The server is local in our office, but I'm unable to just make a script on the afp server side. On my machine, I use something like this:
$filesInDir = array();
$filesInMySQL = array();
if (is_dir($uploadDir)) {
$dh = opendir($uploadDir);
if ($dh) {
$file = readdir($dh);
while ($file != false) {
$path = $uploadDir . "/" . $file;
$type = filetype($path);
if ($type == "file" && $file != ".DS_Store" && $file != "index.php") {
$filesInDir[] = $file;
}
$file = readdir($dh);
}
closedir($dh);
} else {
echo "Can't open dir " . $uploadDir;
}
} else {
echo $uploadDir . " is not a folder";
}
But I can't connect to the afp server. I've looked into fopen it doesn't allow afp, and I don't think it'd allow directory listing:
opendir("afp://ServerName/path/to/dir/");
Warning: opendir() [function.opendir]: Unable to find the wrapper "afp" - did you forget to enable it when you configured PHP? in...
Warning: opendir(afp://ServerName/path/to/dir/) [function.opendir]: failed to open dir: No such file or directory in...`
I'm not looking to see if a file exists, but to get the entire directory listing. Eventually I'll also have to remotely copy files into an output directory.
eg.
mkdir afp://ServerName/output/output001/
cp afp://ServerName/path/to/dir/neededfile.txt afp://ServerName/output/output001/
Maybe use http://sourceforge.net/projects/afpfs-ng/ to mount it...
I'm developing on an Mac Mini, so I realised I could just mount the afp share, and use readdir. I had to mount the drive using the following:
sudo -u _www mkdir /Volumes/idisk
sudo -u _www mount_afp -i afp://<IP>/sharename/ /Volumes/idisk/
Further details here