Using shell with Zend Framework - php

I'm curios if Zend has a component which can make use of the shell. For example I want to do an shell command like this:
mysqldump --compact --uroot --ppass mydatabase mydable >test.sql
from a controller.
If there isn't, do you know a way how to dump data from tables in Zend Framework?
update:
I've found a way here http://www.zfsnippets.com/snippets/view/id/68

There's no direct exec() support in the zend framework. the closest to command line support there is the Zend_Console class, but it's meant for getting arguments from the command line.
I would wrap the exec() function as a process object and work with that. Here's a nice example from the php docs:
<?php
// You may use status(), start(), and stop(). notice that start() method gets called automatically one time.
$process = new Process('ls -al');
// or if you got the pid, however here only the status() metod will work.
$process = new Process();
$process.setPid(my_pid);
?>
<?php
// Then you can start/stop/ check status of the job.
$process.stop();
$process.start();
if ($process.status()){
echo "The process is currently running";
}else{
echo "The process is not running.";
}
?>
<?php
/* An easy way to keep in track of external processes.
* Ever wanted to execute a process in php, but you still wanted to have somewhat controll of the process ? Well.. This is a way of doing it.
* #compability: Linux only. (Windows does not work).
* #author: Peec
*/
class Process{
private $pid;
private $command;
public function __construct($cl=false){
if ($cl != false){
$this->command = $cl;
$this->runCom();
}
}
private function runCom(){
$command = 'nohup '.$this->command.' > /dev/null 2>&1 & echo $!';
exec($command ,$op);
$this->pid = (int)$op[0];
}
public function setPid($pid){
$this->pid = $pid;
}
public function getPid(){
return $this->pid;
}
public function status(){
$command = 'ps -p '.$this->pid;
exec($command,$op);
if (!isset($op[1]))return false;
else return true;
}
public function start(){
if ($this->command != '')$this->runCom();
else return true;
}
public function stop(){
$command = 'kill '.$this->pid;
exec($command);
if ($this->status() == false)return true;
else return false;
}
}
?>
It's also let you stop and check the status of a job.

Related

How to add cron jobs dynamically by reading from file, irrespective of server

I want to add cron job dynamically once user install a php application on their server, like admin configuration, I need to set cron job dynamically once going thought its configuration settings in php?
I am using codeigniter to set the cron job, also I added the same from cpanel manually and it is working fine.
You can create a file in
/etc/cron.d
and use PHP's file_put_contents() to update the file. However, you'll need to elevate PHP or Apache's permissions (depending on your PHP handler). This isn't recommended since it leads to security issues.
If you're using Cron to run PHP scripts, then you can call the scripts directly using PHP every X amount of time. Create a variable in your database representing the last time your script was run. If X amount of time passed since the script was run, then you run the script and update the variable.
If the script takes a long time to execute, then use PHP to run it in a separate process, so the user doesn't have to wait for it to finish.
Thanks
First You have to create one txt file for example crontab.txt
then you have to use shell script like below
exec ( 'sudo crontab -u apache -r' );
file_put_contents ( '/var/www/html/YOUR_PROJECT/crontab.txt',"25 15 * * * php /var/www/html/YOUR_PROJECT/YOUR_CONTROLLER/YOUR_METHOD'.PHP_EOL);
And Lastly, you have to execute that file like
exec ( 'crontab /var/www/html/YOUR_PROJECT/crontab.txt' );
Hope this will help you.
you can do this using shell script
shell_exec('echo "25 15 * * * <path to php> /var/www/cronjob/helloworld.php > /var/www/cronjob/cron.log" | crontab -')
you can use these functions or class
class Crontab {
// In this class, array instead of string would be the standard input / output format.
// Legacy way to add a job:
// $output = shell_exec('(crontab -l; echo "'.$job.'") | crontab -');
static private function stringToArray($jobs = '') {
$array = explode("\r\n", trim($jobs)); // trim() gets rid of the last \r\n
foreach ($array as $key => $item) {
if ($item == '') {
unset($array[$key]);
}
}
return $array;
}
static private function arrayToString($jobs = array()) {
$string = implode("\r\n", $jobs);
return $string;
}
static public function getJobs() {
$output = shell_exec('crontab -l');
return self::stringToArray($output);
}
static public function saveJobs($jobs = array()) {
$output = shell_exec('echo "'.self::arrayToString($jobs).'" | crontab -');
return $output;
}
static public function doesJobExist($job = '') {
$jobs = self::getJobs();
if (in_array($job, $jobs)) {
return true;
} else {
return false;
}
}
static public function addJob($job = '') {
if (self::doesJobExist($job)) {
return false;
} else {
$jobs = self::getJobs();
$jobs[] = $job;
return self::saveJobs($jobs);
}
}
static public function removeJob($job = '') {
if (self::doesJobExist($job)) {
$jobs = self::getJobs();
unset($jobs[array_search($job, $jobs)]);
return self::saveJobs($jobs);
} else {
return false;
}
}
}
Hi thank you for the replies, i got my answers now, based on the replies
I tried to add a new cron job to crontab file using php (codeigniter):
following is my answer
$phppath = exec('which php');
$user_file_path = getcwd();
$cronjob1 = "0 0 1 * * $phppath $user_file_path/index.php
automatic_updates/leave_update_cron";
// run each cron job
// get all current cron jobs
$output = shell_exec('crontab -l');
// add our new job
file_put_contents('/tmp/crontab.txt', $output.$cronjob1.PHP_EOL);
// once append the job, execute the new file
exec('crontab /tmp/crontab.txt');
This will add a new cron job without deleting anything on the current cron job file

Trying to amemd CronJob's Via a PHP file

I have a hosting platform that at midnight resets all cronjob added on there system to 15 from what ever they where set to. Our plan is to set up a script that run's every 8hrs and resets these back, so the process they manage are minimally interrupted. It is shared hosting, but hosting companies solution it an upgrade and a massive rise in costs.
The server specs are cPanel Version - 70.0 (build 69) | Apache Version - 2.4.39 |PHP Version - 7.2.18 |MySQL Version - 10.2.24-MariaDB-cll-lve |Architecture - x86_64 | Operating System - linux
We have been suggested using a PHP class called Crontab to achieve this.
When we add a job, it appears in our cron job section of our server, but if we try to delete it from the server we get the following error 'Error New Lines are not permitted in crontab entries'. How ever we can remove the job via the Crontab class.
<?php
class Crontab {
static private function stringToArray($jobs = '') {
$array = explode("\r\n", trim($jobs)); // trim() gets rid of the last \r\n
foreach ($array as $key => $item) {
if ($item == '') {
unset($array[$key]);
}
}
return $array;
}
static private function arrayToString($jobs = array()) {
$string = implode("\r\n", $jobs);
return $string;
}
static public function getJobs() {
$output = shell_exec('crontab -l');
return self::stringToArray($output);
}
static public function saveJobs($jobs = array()) {
$output = shell_exec('echo "'.self::arrayToString($jobs).'" | crontab -');
return $output;
}
static public function doesJobExist($job = '') {
$jobs = self::getJobs();
if (in_array($job, $jobs)) {return true;} else {return false;}
}
static public function addJob($job = '') {
if (self::doesJobExist($job)) {
return false;
} else {
$jobs = self::getJobs();
$jobs[] = $job;
return self::saveJobs($jobs);
}
}
static public function removeJob($job = '') {
if (self::doesJobExist($job)) {
$jobs = self::getJobs();
unset($jobs[array_search($job, $jobs)]);
return self::saveJobs($jobs);
} else {
return false;
}
}
}
//$output = shell_exec('crontab -l'); //Check server output
//echo nl2br($output); //Make it readable
Crontab::addJob('*/15 * * * * /opt/alt/php56/usr/bin/php -q /home/path/bob.php process-log >/dev/null 2>&1');
Crontab::removeJob('*/15 * * * * /opt/alt/php56/usr/bin/php -q /home/path/bob.php process-log >/dev/null 2>&1');
?>
The reason this is a concern is that for there to be a server error, then code inputting the cronjob must not be doing it right, I have hear of issue when running similar processes on windows servers, but the php file running the code is in the root of the linux server, so wasn't expecting to have issues.
IF someone could explain why this error is occurring and how to fix it, that would be greatly appreciated, let me know if you need any more info.
Cheers in advance.

Parellel tasks in Laravel Scheduling

I basically have a system that's theoretically just a bot, I need to run it on multi-threads (yes I know, it's PHP so not entirely possible) or somewhere along the lines of being able to run an artisan command parallel based on an Eloquent result.
Currently my system looks something like this:
This is my Kernel.php
protected $commands = [
Commands\RunBuy::class
]
protected function schedule(Schedule $schedule)
{
$schedule->command('buy:cron')->everyMinute();
}
This is my RunBuy.php
public function __construct() {
parent::__construct();
}
public function handle() {
$this->bot = Bots::where('status', '1')->where('in_use', '0')->first();
.......
}
I basically need the same capability but being able to manage multiple Bots depending on how many rows their is? what I'd like to be able to do is something like so:
protected function schedule(Schedule $schedule)
{
foreach(Bots::where('status', '1')->where('in_use', '0')->get() as $bot) {
$schedule->command('buy:cron '.$bot->id)->everyMinute();
}
}
And then handle it inside the RunBuy.php like so:
protected $signature = 'buy:cron {bot_id : The Bot ID we must perform actions with}';
public function __construct() {
parent::__construct();
}
public function handle() {
$bot_id = $this->argument('bot_id');
$this->bot = Bots::find($bot_id);
.......
}
But something like this wouldn't work since Laravel process each command one after another? I need them all to fire off at the same time.
If you are on a linux system you can call a command directly with final & to fork the process
$schedule->exec('php artisan buy:cron ' . $bot->id . ' > /dev/null &')->everyMinute();
On windows you can add a scheduled process to be called to run (a batch which accepts 1 param)
and call it as
$schedule->exec('schtasks /run /tn yourtask.bat ' . $bot->id)->everyMinute();
yourtask.bat should be a simple php artisan call
cd /path/to/project && php artisan buy:cron %1
or you can launch each process in background
function execInBackground($cmd) {
try {
if (substr(php_uname(), 0, 7) == "Windows") {
pclose(popen("start /B " . $cmd, "r"));
} else {
exec($cmd . " > /dev/null &");
}
} catch (\Exception $ex) {
throw $ex;
}
}

php zookeeper watcher doesn't work

I'm trying to use zookeeper in a php app, and I've done most of the get($path)/set($path, $value)/getChildren($path) functions following https://github.com/andreiz/php-zookeeper, except the watch_callback function that just doesn't work.
My php version is 5.6.14 and thread safety disabled, and I'm using apache2.4.
Here is some code snippet
class Zookeeper_Module {
private $zookeeper;
public function __construct(){
$this->ci = & get_instance();
$zookeeper_server = $this->ci->config->item('zookeeper_server');
$this->zookeeper = new Zookeeper($zookeeper_server);
}
public function set($path, $value){
$this->zookeeper->set($path, $value);
}
public function get($path, $watch_cb = null){
return $this->zookeeper->get($path, $watch_cb);
}
public function get_watch_cb($event_type = '', $stat = '', $path = ''){
error_log('hello from get_watcher_cb');
$value = $this->get($path, array($this, 'get_watch_cb'));
// update redis cache
$this->ci->cache->redis->save('some cache key', $value);
}
}
class MyTest{
public function get(){
$zookeeper = new Zookeeper_Module ();
$value = $zookeeper->get( '/foo/bar', array (
$zookeeper,
'get_watch_cb'
) );
}
public function set(){
$zookeeper = new Zookeeper_Module ();
$zookeeper->set( '/foo/bar', 'some value');
}
}
I can successfully get or set a node value, but I can neither catch watch callback log nor have redis cache updated.
I write a more simple demo, very similar with this https://github.com/andreiz/php-zookeeper/wiki, and the watcher works fine in this demo.
The most significant difference is
while( true ) {
echo '.';
sleep(2);
}
While java has a jvm container hosting watchers, php doesn't has a container to do it, so we have to use a while(true) to keep watchers alive.
So I add a while(true) in my code and now the watcher works fine.
But I don't want to add a terrible while(true) in a web app, so the final solution is adding a java app to communicate with zookeeper and save results in redis, and php app just reads info from redis.

php shell_exec not working on windows

I am on Windows. I have a string as follows
Ra6tRR8DIsoll/7O5o6DBfRvlbhdj4mGmivRXYiDHD1JpY1WIMpI5HycXp/IsnUF
What I am trying to do is perform a shell_exec from php to my console app . The console app command line is as follows
consoleapp decrypt Ra6tRR8DIsoll/7O5o6DBfRvlbhdj4mGmivRXYiDHD1JpY1WIMpI5HycXp/IsnUF
However when I try to run shell_exec using the command above I get a null as a result. the command works on the console, though.
Is it because there are special characters in the string ? I was looking at escapeshellarg and wondering if it could help resolve this issue ?
following is my code . I am calling the doDecreyptWithTime method.
private function doDecryptWithTime($string)
{
$command = "aesencryptdecrypt.exe decrypt ". escapeshellarg(trim($string));
// dd($command);
return exec($command);
}
private function doDecrypt($string)
{
$command = $this->generateEntireCommand(EncryptionCommands::Decrypt). ' ' .$string;
return shell_exec($command);
// return explode(Config::get('myconfig.DecryptDelimiter'),$output);
}
private function generateEntireCommand($command)
{
if($command == EncryptionCommands::Encrypt)
return $this->generatePath(). ' '. EncryptionCommands::Encrypt;
elseif($command == EncryptionCommands::Decrypt)
return $this->generatePath(). ' '.EncryptionCommands::Decrypt;
elseif($command == EncryptionCommands::DecryptWithTime)
return $this->generatePath(). ' '.EncryptionCommands::DecryptWithTime;
}
private function generatePath()
{
$fullEncryptFileName = null;
$encryptFileName = Config::get('myconfig.EcryptionFileName');
if(!is_null(Config::get('myconfig.EcryptionFileName')))
{
$fullEncryptFileName = public_path().DIRECTORY_SEPARATOR.Config::get('myconfig.EncryptFileLocation').DIRECTORY_SEPARATOR.$encryptFileName;
}
else
{
$fullEncryptFileName = public_path().DIRECTORY_SEPARATOR.$this->fileLocation.DIRECTORY_SEPARATOR.$encryptFileName;
}
if(!is_null($fullEncryptFileName))
return $fullEncryptFileName;
else
throw new Exception('could not generate the filename');
}
Update 1 :
I am on php 5.5 so i Believe that the safe_mode functionality is not available any more. Also I have checked the disabled functions list, shell_exec, exec are not listed there .
please suggest!

Categories