I have a Laravel app that needs to run a shell script, to do so I'm using exec(). The shell script creates a file that I want to store in my storage folder, however the shell script requires the path for the storage folder.
If I use storage_path() it returns something like "/home/vagrant/project/storage" which works fine when it comes to referencing things within my web app, but as far as the shell script is concerned isn't correct.
The correct path on homestead would be: ~/project/storage and on live/staging it would be something like /var/www/project/storage.
Is there a elegant way of Laravel acquiring the exact path to pass to the shell script or am I going to have to specify it in my .env file and use that instead?
Default value returned by storage_path() always points to storage/ folder in your project's root. Regardless in which folder you put your project application, value returned by the helper will be correct.
If you want to change the default value of storage_path, you can do so with App::useStoragePath($path). If this value should be different for different environments you need to read the path from .env file - that's what it is for.
App::useStoragePath(env('STORAGE_PATH'));
Related
I have two PHP versions that I want to execute depending on the situation. I have setup PATH so that when I type php there is executed the right version of PHP in the folder C:\xampp\php.
However, I also have an older version of PHP in the folder C:\old-xampp\php. Of course, I can't add also that folder path to PATH as there would be two folders with a file with the name php.exe and used would be always php.exe in first folder in PATH.
At the moment I have to type C:\old-xampp\php\php my-command-here every time I want to execute my old PHP.
Is there a way to create a .bat file in a PATH folder with the name old-php.bat that would act as if I typed C:\old-xampp\php\php?
I am open to another method to do it too.
There can be written into a batch file old-php.bat stored in a folder of which path is listed in string value of environment variable Path the command line:
#C:\old-xampp\php\php.exe %*
%* references all arguments passed to the batch file exactly as passed to the batch file. This is explained by the usage help of command CALL output on running call /? in a command prompt window. Argument 0 is the string used to start the batch file which is not included by %*.
It would be also possible to create in a folder of which path is listed in string value of environment variable Path a hard link or a symbolic link with a name like old-php.exe which links to C:\old-xampp\php\php.exe by using once MKLINK.
I have a php script that should run a command located in a certain subfolder, in another subfolder.
The command is in folder Cmd, and should be executed in folder 1.6.2. So first I switch to the 1.6.2 directory, and then I use a relative path to call the command:
exec("cd 1.6.2");
exec("..\Cmd\sencha app build production");
But this throws the error that the directory couldn't be found, because the second exec still executes in the main folder, where the calling index.php file resides.
The php manual on exec doesn't provide any possibility to execute in another directory. Am I missing something here?
The current system is a Windows, but I have to make it portable because it may be executed on linux in the future.
Try changing the working directory first
e.g.
chdir('/path/to/1.6.2');
exec("sencha app build production");
You have to change the directory within the same exec() command.
like so: exec("cd 1.6.2 && Cmd/sencha app build production"); depending on your actual folder structure. I'm just guessing)
Here is my problem: I have a website running on IIS 7 + PHP 5.3. There is a virtual directory in the website hierarchy called "vd" which contains flash files.
myApplication
- test.php
- vd
- animation1.swf
- animation2.swf
- ...
So, it's easy to reach the swf files with a browser, you just have to put the directory name in the url: http://www.mySite.com/vd/animation1.swf
However, I would like to use the getimagesize() function on my animations in a PHP script. But in this case, php can't find the file:
<?php
// test.php
var_dump(getimagesize('vd/animation1.swf')); // false
?>
It seems to make sense because anyway '/' aren't even the right directory separator for windows. But I just can't figure out how to make getimagesize works through a virtual directory, I tried a lot of stuff without success (using the DIRECTORY_SEPARATOR constant, using realpath() function ...).
Of course, I could use the real path in my script but it would be easier for me to be able to do that throught the virtual path.
Any help would be greaty appreciated,
Thanks!
PHP is not going through the web server but rather the OS to get the file. So, no web server virtual-to-real translations will take place. You will need to use the real path of the file. You could make a web request on the file and deduce the size in that manner but that is very inefficient. It makes much more sense to just do it right through the OS.
Simply create a variable/define/class constant or whatever you prefer to store the real path of the pertinent directory. Then just append animation1.swf to that in your code.
I was wondering if there is some variable that will return what $_SERVER['DOCUMENT_ROOT'] returns when I call PHP like this: ./somescript
If not, how do people get around this case? I'm looking to be able to call the same script (a template compiler) in both the web browser and the terminal.
Thanks!
Matt Mueller
I don't recommend the getcwd() command for this because you cannot be sure of where cwd is pointing unless you've made a chdir before (which mean you already know which directory you're in). Working directory can be define in php config and vary between apache and CLI, and some php frameworks changes it on startup.
Use dirname(__FILE__) it always works wether you're in a apache or cli context (plus it works on windows and unix), and if you need to move inside your project files you can just use relative paths.
I think you should use getcwd function to obtain current directory (or just dirname(__FILE__) if your script is the top one). Then you only need to be sure to run the script from your DOCUMENT_ROOT. Something like this:
cd /var/www/
php ./scripts/top.php
hardcode document root in it.
hardcode is always a solution
I'm using $_SERVER['DOCUMENT_ROOT'] for my include paths so files will figure out where they are running from (i.e. whether they're on live or staging) and it works fine, except for scripts that are run by cron in which I have to hardcode the path.
Is there another variable I could use that could work from both cron and the browser?
When running your PHP script through cron, I assume it is executed in the context of the CLI instead of the web server. In the case of executing PHP from the CLI, the $_SERVER['DOCUMENT_ROOT'] is not populated correctly. You can use the following code to work around this:
if ($_SERVER['DOCUMENT_ROOT'] == "")
$_SERVER['DOCUMENT_ROOT'] = dirname(__FILE__);
The following will give you the directory that your script is located in:
realpath(dirname(__FILE__));
This works for both web requests and cron scripts.
The best thing to do is to define your own constant that you can reference from anywhere else in your app. For example, you can put something like this in MyAppDirectory/public_html/index.php:
define('APPLICATION_PATH', realpath(dirname(__FILE__).'/..'));
This will give you a consistent reference back to MyAppDirectory/ regardless of where index.php is called or included from. Defining your own constant not only allows you to call your application from cron or through the browser like you want, but will also allow you to change your storage structure in much larger ways with minimum changes to track down. Zend Framework uses this heavily with its Zend_Application bootstrap process, and googling for "php APPLICATION_PATH" will provide you with a variety of further references.
You can use chdir() function, if your script is running via cron:
chdir(dirname(__FILE__)); //avoid conflict with "cron path" and app base path (if script runs via 'Cron')
I work on Windows, so use "nnCron", but it have to work on Linux too.