I have a PHP application running in the Linux subsystem for Windows.
The application talks to an external .exe file that requires a filename as an input.
In my PHP application, I need to determine if the file exists before trying to send it to the external .exe file.
To summarise, when in my PHP application I need the Linux file path, but when passing it as an argument to the .exe I need the windows file path.
So it would look something like this:
<?php
$fn = '/mnt/c/myapp/myfile.png';
$exists = file_exists($fn);
if ($exists) {
shell_exec('external.exe -f ' . transformToWindowsPath($fn));
}
function transformToWindowsPath($fn)
{
// What should go here?
// Is something like this reliable?
return str_replace(
'/',
DIRECTORY_SEPARATOR,
preg_replace_callback(
'/\/mnt\/([a-zA-Z])\//',
function($matches) {
return strtoupper($matches[1]) . ":" . DIRECTORY_SEPARATOR;
},
$fn
)
);
}
Try with this function that converts the directory separator:
$fn = '/mnt/c/myapp/myfile.png';
function fnSystem($fn, $system='linux')
{
if($system == 'windows')
{
$fn = str_replace('/mnt/c/', '', $fn); // remove /mnt/c/ from front
$fn = str_replace('/', '\\', $fn); // convert the directory separator
$fn = "C://$fn"; // place C:// in front
}
elseif($system == 'linux')
{
$fn = str_replace('C://', '', $fn); // remove C:// from front
$fn = str_replace('\\', '/', $fn); // convert the directory separator
$fn = "/mnt/c/$fn"; // place /mnt/c/ in front
}
return $fn;
}
$fnWindows = fnSystem('/mnt/c/myapp/myfile.png', 'windows');
echo $fnWindows;
Result:
C://myapp\myfile.png
Related
Below I have left my code. It currently works in my development environment (localhost), but when I push the changes to my live server it seems like my php doesn't create the folder/file.
public static function saveImage($image, $name, $path = '')
{
$img_data = explode(',', $image);
$mime = explode(';', $img_data[0]);
$data = $img_data[1];
$extension = explode('/', $mime[0])[1];
if(!file_exists('../public/media/img/' . $path)){
mkdir('../public/media/img/' . $path, 0755);
echo('Test1');
}
echo('test2');
file_put_contents('../public/media/img/' . $path . $name . '.' . $extension, base64_decode($data));
return 'media/img/' . $path . $name . '.' . $extension;
}
Locally it will hit echo('test1') the first time, then it will only hit echo('test2'). When its on the server it always hits the echo('test1')
By default mkdir is not create a path recursively. An example if on your server you dont have a ../public/media folder, mkdir returns false and dont create a path.
To solve this pass a third parameter to mkdir as true:
mkdir('../public/media/img/' . $path, 0755, true);
Do yourself a favour and use absolute pathes...
You can use the constant __DIR__ to evaluate the folder in which the script actually resides.
Relative pathes are calculated from the current working directory, which can be different than __DIR__
I'm using the below function:
class Image {
static function url($id, $type = 'maps') {
$path = UPLOAD_DIRECTORY . '/' . $type . '/';
$files = glob($path . $id . '.*');
if (count($files)) {
$ext = substr($files[0], strpos($files[0], '.') - strlen($files[5]));
return SERVER_URL . 'img/' . $type . '/' . $id . $ext;
} else {
return '';
}
}
}
It works fine when hosted on WAMP but when using on Unix running on nginx it doesn't display the image correctly because of the file path. It seems to add the physical path of the files in the URL so it thinks the patch of the file is http://localhost/demo/img/maps/20/public_html/demo/img/maps/20.png
On WAMP it displays correctly ie the URL is http://localhost/demo/img/maps/20.png
These are the defined variables:
define('SERVER_URL', 'http://localhost/demo/');
define('UPLOAD_DIRECTORY', dirname(__FILE__) . '/img');
id=20;
Physical location of the images are in /public_html/demo/img/maps/
How can I fix this on a unix OS.
Managed to work out a solution (btw I'm not a programmer).
Basically on the UNIX server the directory where the images were located had a dot in the path whereas on wamp it didn't.
So what I had to do is use the strrpost instead of strpost - this finds the position of the last occurrence of a substring in a string instead of the first occurance.
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
So I am trying to use rename function in php.
On the first try, if the destination folder is empty or does not contain any directories with the same name as the source folder the rename function works perfectly. However, if there is same directory name it fails. What I want is just to overwrite it and I thought rename() would suffice.
Here is my code:
/**
* Move temp folders to their permanent places
*
* $module_folder = example (violator, pnp, etc)
* $folders = name of folders within module_folder
**/
public function move_temp_to_permanent($module_folder, $folders){
$bool = false;
$module_folder_path = realpath(APPPATH . '../public/resources/temps/' . $module_folder);
$module_folder_destination_path = $_SERVER['DOCUMENT_ROOT'] . '/ssmis/public/resources/photos/' . $module_folder . '/';
foreach($folders as $folder){
$bool = rename($module_folder_path . '/' . $folder, $module_folder_destination_path . $folder);
}
return $bool;
}
The code above gives me an error saying:
Message:
rename(C:\xampp\htdocs\ssmis\public\resources\temps\violator/SJ-VIOL-2015-0002,C:/xampp/htdocs/ssmis/public/resources/photos/violator/SJ-VIOL-2015-0002):
Access is denied. (code: 5)
I am using CodeIgniter as framework.
Thank you very much!
If it is on Windows, this can be read in contributions:
rename() definitely does not follow the *nix rename convention on WinXP with PHP 5. If the $newname exists, it will return FALSE and $oldname and $newname will remain in their original state. You can do something like this instead:
function rename_win($oldfile,$newfile) {
if (!rename($oldfile,$newfile)) {
if (copy ($oldfile,$newfile)) {
unlink($oldfile);
return TRUE;
}
return FALSE;
}
return TRUE;
}
Link.
You are adding extra / in path make this like
/**
* Move temp folders to their permanent places
*
* $module_folder = example (violator, pnp, etc)
* $folders = name of folders within module_folder
**/
public function move_temp_to_permanent($module_folder, $folders){
$bool = false;
$module_folder_path = realpath(APPPATH . '../public/resources/temps/' . $module_folder);
$module_folder_destination_path = $_SERVER['DOCUMENT_ROOT'] . '/ssmis/public/resources/photos/' . $module_folder . '/';
foreach($folders as $folder){
$bool = rename($module_folder_path . $folder, $module_folder_destination_path . $folder);
}
return $bool;
}
you can also echo the path you prepared so you can check its right or not
I want to print out the current URL path, but my code doesn't work propperly.
I use this in my file.php
echo "http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
When i open the url http://sub.mydomain.com/file.php it seems to work fine, and it prints "http://sub.mydomain.com/file.php"
But if i remove the .php extension so the url will be http://sub.mydomain.com/file instead, it prints "http://sub.mydomain.com/sub/file.php" which is wrong.
It prints the subdomain twice, and I don't know why?
In my .htaccess file, I have a rewrite that makes it possible to removes .php extensions.
Anyone who can/want to help me please? :)
You need $_SERVER['REQUEST_URI'] instead of $_SERVER['SCRIPT_NAME'], cos $_SERVER['SCRIPT_NAME'] will always give you the file which is working at the moment.
From manual:
SCRIPT_NAME: Contains the current script's path. This is useful for pages which need to point to themselves. The __FILE__ constant contains the full path and filename of the current (i.e. included) file. .
I suppose this helps you getting current URL fully.
echo 'http://'. $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
Notice: DO NOT RELY ON CLIENT'S HTTP_HOST, USE SERVER_NAME INSTEAD! SEE: What is the difference between HTTP_HOST and SERVER_NAME in PHP?
Security Warning
You need to filter (sanitize) $_SERVER['REQUEST_URI'] if you use it in anywhere (to print or store in database), cos it's not safe.
// ie: this could be harmfull
/user?id=123%00%27<script...
Hence, always filter user inputs before using them. At least use htmlspecialchars, htmlentities, strip_tags etc..
Or something like this;
function get_current_url($strip = true) {
static $filter, $scheme, $host, $port;
if ($filter == null) {
$filter = function($input) use($strip) {
$input = trim($input);
if ($input == '/') {
return $input;
}
// add more chars if needed
$input = str_ireplace(["\0", '%00', "\x0a", '%0a', "\x1a", '%1a'], '',
rawurldecode($input));
// remove markup stuff
if ($strip) {
$input = strip_tags($input);
}
// or any encoding you use instead of utf-8
$input = htmlspecialchars($input, ENT_QUOTES, 'utf-8');
return $input;
};
$scheme = isset($_SERVER['REQUEST_SCHEME']) ? $_SERVER['REQUEST_SCHEME']
: ('http'. (($_SERVER['SERVER_PORT'] == '443') ? 's' : ''));
$host = $_SERVER['SERVER_NAME'];
$port = ($_SERVER['SERVER_PORT'] != '80' && $scheme != 'https')
? (':'. $_SERVER['SERVER_PORT']) : '';
}
}
return sprintf('%s://%s%s%s', $scheme, $host, $port, $filter($_SERVER['REQUEST_URI']));
}
$main_folder = str_replace('\\','/',dirname(__FILE__) );
$document_root = str_replace('\\','/',$_SERVER['DOCUMENT_ROOT'] );
$main_folder = str_replace( $document_root, '', $main_folder);
if( $main_folder ) {
$current_url = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME']. '/' . ltrim( $main_folder, '/' ) . '/';
} else {
$current_url = $_SERVER['REQUEST_SCHEME'].'://'.rtrim( $_SERVER['SERVER_NAME'], '/'). '/';
}