How can I execute shell script file from laravel app - php

I have commands in a shell script file and I need to execute it when certain event happen in my app, I search in google to find a better way to do it so I found Symfony library called process, but I don't know how to send parameters to the shell script file cause my file will receive some arguments actually three arguments, and file located in path /home/user/myfile.sh.
Inside my controller look like :
public function store()
{
$process = new Process('/home/user/myfile.sh', null, [
'a',
'b',
'c'
]);
$process->run();
return $process->getOutput();
}
when executing my function nothing happen jus get a response 200, can someone help me what is going on what is my fault or anything?

Your codes look good. Problem at your myfile.sh. Please make sure bash script returns somethings.

Related

A way to call a command prompt function from controller in Laravel?

I'm trying to make a thumbnail in a Laravel project and I tried a lot other ways but with no success - Libraries, APIs... The problem is that the project is developed in Windows and the professor needs it in Windows as well.
So far, I experimented to integrate different libraries (wkhtmltoimage, spatie/browsershot, mpdf and s.o.) but in the most of the cases, there are problems with the path.
The required function, which I need, works very good in command prompt and I thought that I must find a way to call it in the controller.
I've tried with:
shell_execute($call);
system($call);
exec($call);
// with $call = "{func_name} {path_to_input_file} {name_of_output_file}";
// Example: $call = "wkhtmltoimage C:\xampp\htdocs\app\public\test.html img.jpg"
But no result. The function generates an image, which I want to store in the database.
Is there an other way to make a call to the command prompt?
Maybe SSH call?
You can execute Artisan commands directly via your controller.
Look at this example from the Laravel documentation:
Route::get('/foo', function () {
$exitCode = Artisan::call('email:send', [
'user' => 1, '--queue' => 'default'
]);
//
});

Call artisan command from the same command

In the handle of your custom Laravel command, can you call the command again? Like this, described using sort of pseudo-code:
public function handle() {
code..
code..
$this->importantValue = $this->option('value'); //value is 'hello'
if(something) {
//call of the same command is made, but with different arguments or options
//command does stuff and ends successfully
$this->call('myself' [
'value' => 'ahoy'
];
//I expect the handle to be returned to the original command
}
var_dump($this->importantValue); //this equals 'ahoy'
}
Why is this? What does that newly called command has in common with the original within which it had been called?
EDIT: The newly called command would not reach the condition something it would not call itself again (forever). The original command seems to pick up from where it left (before calling itself the first and only time) yet it seems it has had inherited the "children's" variables.
I do think that calling Artisan::call() instead of $this->call() might avoid that problem (note that avoiding is not the same as solving)...
#t-maxx: I'm getting the exact same issue and I'm not sure that #ben understands.
I have a command that is recursive, based on an argument, depth. The depth argument is set to a protected property as one of the first steps in handle(). Then, if depth is greater than zero, it calls itself (via $this->call()), but passing $this->depth - 1. I watch each successive call and it just goes down and down and down, never plateauing or bouncing up was the recursion would allow and as one would expect.
So...while I'm not 100% sure what's going on, I'm thinking of getting the depth option once, but passing it around as a variable (versus a property on the object). This is ugly, I think, but it may be the only solution until this is recognized and resolved. On the other hand, it could be that we're both doing the wrong thing.
Calling Artisan::call() for me leads to other issues that I'd rather avoid. The command I'm working with writes to a file and I don't want a bunch of separate commands competing for the same file.
Yes, you can Programmatically Executing Commands using Artisan::call
Artisan::call('myself', [
'value' => 'ahoy'
]);

How to create a Cakephp 3 Shell that overwrites files without asking permission

I'm using Cakephp 3.2, which is awesome!
I have a shell script is very politely asking if I want to overwrite my files -I'm worried the shell won't complete its intended outcome when run as a cron job.
#example of current shell output
File 'webroot/example.json' exists
Do you want to overwrite? (y/n/a/q)
The docs say: "If the shell’s interactive property is false, no question will be asked and the file will simply be overwritten." (http://book.cakephp.org/3.0/en/console-and-shells.html#creating-files) This seems to suggest that any shell can alter the "interactive" property but I haven't found a way to do that.
I could probably change this to false (http://api.cakephp.org/3.2/source-class-Cake.Console.Shell.html#84), but I think that would affect all shells, no thank you.
Example Code:
class ExampleShell extends Shell {
public function initialize() {
parent::initialize();
}
public function main() {
$array = [1,2,3];
$this->createFile('webroot/example.json', json_encode($array)); //this file already exists
}
}
?>
tl;dr
Please let me know how I can make a single shell script's interactive property set to false so that it won't require a user to allow files to be overwritten. Please provide a code sample if possible, solution must not be applied globally.
Thank you.
Thanks to #AD7six for the comment that helped me see the bigger picture. I was able to replace a line of code and now my cron jobs work!
//replaced this
$this->createFile('webroot/example.json', json_encode($array));
//with this
file_put_contents('webroot/example.json', json_encode($array));

Is there any way to instantiate CodeIgniter and call a function inside a controller from an outside class?

I am creating a cron job that will run every few minutes and it will read from database data to see which function needs to be called and act accordingly to the data but half the crons are written in codeigniter and the other half in native php.
Is there any way to do this? I have been googling but the anwser. I came up with is that it is impossible. I tried changing directory and than including or requiring index.php from the codeigniter, in which the function is that i need to call.
while doing this if my class is written in native php, It returns some errors that don't make sense and if I correct those errors, I would say that half the system function from codeigniter would be gone. It would still be a question if it will work even then.
If my class is written in codeigniter, when I include index.php, it just breaks. No errors no response or it says that the "ENVIRONMENT" variables are already defined. Thus I have been looking for a way to undefine those variables from config file or overwrite them to null or empty string but nothing works.
If you have any ideas it would be much appreciated.
I saw a question question link about some cron jobs in php where the user #michal kralik gave an answer about what i am doing in general with database and one cron class that will call other crons (coould use help for that too).
btw forgot to mention that using curl and exec will not work, because on our servers they sometimes just stop working for no reason.
UPDATE 1:
this is my class currently after so many tries:
class Unicron extends MY_Controller {
public $config;
function __construct() {
parent::__construct();
}
public function init(){
$config['base_url'] = "http://localhost/test";
define('EXT_CALL', true); // Added EXT_CALL constant to mark external calls
$_GET['controller/method'] = ''; // add pair to $_GET with call route as key
$current = getcwd(); // Save current directory path
chdir('C:/inetpub/wwwroot/test/'); // change directory to CI_INSTALLATION
include_once 'index.php'; // Add index.php (CI) to script
define('BASEPATH', 'C:/inetpub/wwwroot/test/system/');
$this->load->library("../../application/controllers/controller.php");
$job = new $this->controller->Class();
$isDone = $job->exportExcel(somekey);
echo $isDone;
$CI =& get_instance(); // Get instance of CI
$CI->exportExcel('baseparts', 'exportExcel');
// FOR STATIC CALLING!!
//$CI->method('controller','method');
//replace controller and method with call route
// eg: $CI->list('welcome','list'); If calling welcome/list route.
//$OUT->_display(); // to display output. (quick one)
// Or if you need output in variable,
//$output = $CI->load->view('VIEW_NAME',array(),TRUE);
//To call any specific view file (bit slow)
// You can pass variables in array. View file will pick those as it works in CI
chdir($current); // Change back to current directory
echo $current;
}
where i try to define BASEPATH it does not define it nor override the previous value.
In the index.php of other codeigniter i put:
if(!defined('ENVIRONMENT'))
define('ENVIRONMENT', 'development');
this way i resolved my issue with ENVIRONMENT already being set error.
this is a few things i found and combined together, hoping it could work but still when i call it via command line it shows nothing (even tried echo anything everywhere and nothing).
This may be a long comment rather than a answer as the code supplied requires a lot of work to make it useful.
Running multiple instances of 'codeigniter' - executed from codeigniter.
Using the 'execute programs via the shell' from PHP. Each instance runs in its own environment.
There are some excellent answers already available:
By default the PHP commands 'shell' wait for the command to complete...
732832/php-exec-vs-system-vs-passthru.
However, we want to 'fire and forget' quite often so this answer is quite useful...
1019867/is-there-a-way-to-use-shell-exec-without-waiting-for-the-command-to-complete
All i did was use this show an example of how to use 'codeigniter' to do this. The example was the 'Hello World' cli example from user manual. The version of ci is 2.1.14. I haven't used 'ci' before.
It is tested and works on 'PHP 5.3.18' on windows xp.
As well as the usual 'Hello World' example, i used an example of a a command that uses 'sleep' for a total of 20 seconds so that we can easily see that the 'ci' instances are separate from each other while executing.
Examples:
<?php
class Tools extends CI_Controller {
// the usual 'hello world' program
public function message($to = 'World')
{
echo "Hello {$to}!".PHP_EOL;
}
// so you can see that the processes are independant and 'standalone'
// run for 20 seconds and show progress every second.
public function waitMessage($to = 'World')
{
$countDown = 20;
while ($countDown >= 0) {
echo "Hello {$to}! - ending in {$countDown} seconds".PHP_EOL;
sleep(1);
$countDown--;
}
}
}
'ci' code to run 'ci' code...
<?php
class Runtools extends CI_Controller {
/*
* Executing background processes from PHP on Windows
* http://www.somacon.com/p395.php
*/
// spawn a process and do not wait for it to complete
public function runci_nowait($controller, $method, $param)
{
$runit = "php index.php {$controller} {$method} {$param}" ;
pclose(popen("start \"{$controller} {$method}\" {$runit}", "r"));
return;
}
// spawn a process and wait for the output.
public function runci_wait($controller, $method, $param)
{
$runit = "php index.php {$controller} {$method} {$param}";
$output = exec("{$runit}");
echo $output;
}
}
How to run them from the cli...
To run the 'ci' 'nowait' routine then do:
php index.php runtools runci_nowait <controller> <method> <param>
where the parameters are the ci controller you want to run. Chnge to 'runci_wait' for the other one.
'Hello World: 'wait for output' - (ci: tools message )
codeigniter>php index.php runtools runci_wait tools message ryan3
Hello ryan3!
The waitMessage - 'do not wait for output' - (ci : tools waitMessage )
codeigniter>php index.php runtools runci_nowait tools waitMessage ryan1
codeigniter>php index.php runtools runci_nowait tools waitMessage ryan2
These will start and run two separate 'ci' processes.

cron job: CodeIgniter2+Doctrine2 How do I get this to work?

I am attempting to use cron to run a PHP file that executes a series of actions. I've done this before with simple procedural PHP, the trick then was doing the cron like this:
/usr/local/php5/bin/php /home/me/fullpath/turnrun.php
and having this at the very top of the PHP file I wanted executed.
#!/usr/local/bin/php -q
I'm using CodeIgniter 2 and Doctrine 2, so I have controllers and classes and all kinds of fancy stuff now, and I can't figure out how to make this work.
When I attempt to run a 'backend_test_turn.php' file I get an error
Parse error: syntax error, unexpected T_STRING in
/home/me/fullpath/application/controllers/backend_test_turn.php
on line 59
This file includes
class Backend_test_turn extends CI_Controller {
// code
$logmsg = new ORM\Dynasties2\Systemlog; // <--- this is line 59
// code
}
Note that when I run this normally (in a browser), the code works fine and does not throw an error.
What am I doing wrong?
You can run the controller code directly from command line like this:
php index.php Backend_test_turn/action/data
OR
php index.php Backend_test_turn action data
You can find more help here.
you can try
$logmsg = new ORM\Dynasties2\Systemlog;
$logmsg = new ORM\Dynasties2\Systemlog(); // <- see difference
Did you try to use CURL instead?
I have an application CI & Doctrine with CRON jobs and I've got many errors like yours while trying to launch controllers via CLI.
Personnaly now I use CURL instead of CI CLI and it works like a charm.

Categories