I have the following code:
class IndexController extends pm_Controller_Action
{
public function indexAction()
{
shell_exec('php /usr/local/psa/admin/plib/modules/hello-world/script.php');
$file = file_get_contents( "/usr/local/psa/admin/plib/modules/hello-world/tune" );
var_dump($file);
var_dump(file_exists($file));
$this->view->message = $file ;
}
}
In /views/scripts/index/index.phtml
<?php echo $this->message; ?>
So it basically prints the content of "tune" file on a page, but I want it to execute the shell command (another php script actually) via shell_exec().
The problem is that shell_exec() does not work - script.php doesn't run.
I understand that I'm missing something very important here but can't figure out what.
p.s. sorry for such question - I'm new to php
Related
I installed gearman extension and gearman command line tool also. I tried to reverse a string using gearman from simple php file.
Example:
$gmclient= new GearmanClient();
$gmclient->addServer();
$result = $gmclient->doNormal("reverse", "Test the reverse string");
echo "Success: $result\n";
output:
Success: gnirts esrever eht tseT
In the same way i tried to run exec('ls -l') , I am able to execute using simple php files from cakephp application from webroot directory. filepath: cakephp/app/webroot/worker.php, cakephp/app/webroot/client.php.
worker.php
<?php
$worker= new GearmanWorker();
$worker->addServer();
$worker->addFunction("exec", "executeScript");
while ($worker->work());
function executeScript($job)
{
$param = $job->workload();
$t = exec($param);
return $t;
}
?>
client.php
<?php
$client= new GearmanClient();
$client->addServer();
$cmd = 'ls -l';
print $client->do("exec", $cmd);
?>
How to implement the same type of execution using View, Controller from cakephp?
Workflow: Post data from View to Controller using ajax method and execute "exec() from gearman" , send output back to View as response of ajax POST methhod.
Why are you using exec?! That brings a huge security risk. Use DirectoryIterator instead.
Your client code should be part of the controller.
<?php
class UploadController extends AppController
{
public function directoryList()
{
$directory = '';
// Get data
if (!empty($this->data['directory']) && is_string($this->data['directory']))
{
$directory = $this->data['directory'];
}
$client= new GearmanClient();
$client->addServer("localhost",4730); // Important!!!
$result = $client->do("fileList", serialize($data));
return $result;
}
}
Then from view use requestAction.
$uploads = $this->requestAction(
array('controller' => 'upload', 'action' => 'directoryList'),
array('return')
);
Worker could look like this:
<?php
$worker= new GearmanWorker();
$worker->addServer("localhost",4730); // Important!!!
$worker->addFunction("fileList", "getFileList");
while ($worker->work());
// From Art of Web
// http://www.the-art-of-web.com/php/directory-list-spl/
function getFileList($dir)
{
// array to hold return value
$retval = array();
$dir = $job->workload();
// add trailing slash if missing
if(substr($dir, -1) != "/") $dir .= "/";
// open directory for reading
$d = new DirectoryIterator($dir) or die("getFileList: Failed opening directory $dir for reading");
foreach($d as $fileinfo) {
// skip hidden files
if($fileinfo->isDot()) continue;
$retval[] = array(
'name' => "{$dir}{$fileinfo}",
'type' => ($fileinfo->getType() == "dir") ?
"dir" : mime_content_type($fileinfo->getRealPath()),
'size' => $fileinfo->getSize(),
'lastmod' => $fileinfo->getMTime()
);
}
return $retval;
}
This is pseudo code. Do not use it in production!!! See Gearman documentation for more advance worker setup.
To actually take advantage of load distribution Gearman server should not be on localhost of course.
Your worker.php needs to be already running on a server for this to work. For testing, open up a new terminal window to the server where you want worker.php to run. Start the worker: php worker.php on the command line. (On a production server, you might want to look at supervisor to run your worker without a terminal.)
The code in client.php would go in your controller, but save the result to a variable instead of a print statement.
The fact that this would be from an AJAX call is irrelevant, it will work the same as a normal web page. When the controller executes, the gearman client code will get a response from the worker, and you can output the result to the view.
I have almost successfully setup a Cron job on my server, but I cannot call the correct controller.
When I remove the CLI only if statement I can successfully run the script from my browser.
// Make sure the request is being made by a CRON Job
if ( ! $this->input->is_cli_request()) exit('Only CLI access allowed');
I am having the output being emailed by the Cron Daemon. I have tried this command and following is my results.
job :
/usr/bin/php /home/dlp/public_html/abc.org/index.php birthday
Result :
I get the 2 emails in 1st email HTML output of the default controller index.php and in 2nd email output of birthdady controller.
code of my controller is.
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Birthday extends CI_Controller {
function __construct()
{
parent::__construct();
$this->load->helper('url');
$this->load->database();
$this->load->library('email');
}
/**** function for sending news letter on birthday ****/
function index()
{
error_log("birthday function call",1,"abc#gmail.com");
exit;
}
}
?>
I am not sure what I am doing wrong.
Thanks in advance for the help.
You are writing only controller name in cronjob but you should write method name also when the method is index. So in your case you write birthday/index in your cronjob.
OR
Create cron.php config file in application/config with data as:
$config['CRON_TIME_LIMIT']=0;
$config['argv'] =array(1 => 'birthday');
$config['CRON_BETA_MODE']=false;
Create cron.php at root parrallel to application folder containing data as
//!/usr/bin/php
<?php
define('CRON', TRUE);
// Load CRON config
require('/home/dlp/public_html/abc.org/application/config/cron.php');
// Set CRON mode ( live or beta )
define('CRON_BETA_MODE', $config['CRON_BETA_MODE']);
// Set index.php location
if (isset($config['CRON_CI_INDEX']) && $config['CRON_CI_INDEX'])
define('CRON_CI_INDEX', $config['CRON_CI_INDEX']);
else
define('CRON_CI_INDEX', '/home/dlp/public_html/abc.org/index.php');
if (count($argv) < 2)
if (count($config['argv'])) {
$argv = array_merge($argv, $config['argv']);
$_SERVER['argv'] = $argv;
} else
die('Use: php cron.php controller/method');
// Simulate an HTTP request
$_SERVER['PATH_INFO'] = $argv[1];
$_SERVER['REQUEST_URI'] = $argv[1];
//$_SERVER['SERVER_NAME'] = $config['SERVER_NAME'];
// Set run time limit
set_time_limit($config['CRON_TIME_LIMIT']);
// Run CI and capture the output
ob_start();
chdir(dirname(CRON_CI_INDEX));
// echo "== ".CRON_CI_INDEX; die;
require( CRON_CI_INDEX ); // main CI index.php file
$output = ob_get_contents();
if (CRON_FLUSH_BUFFERS === TRUE)
while (#ob_end_flush()); // display buffer contents
else
ob_end_clean();
echo "\n";
?>
Run cron the file as php
/home/dlp/public_html/abc.org/cron.php
I wrote a service class called search_categorization_service.php. Now I am making a call to python scrpt in this class
class SearchCategorizationService
{
function searcher($query)
{
$tmp=passthru("python serverscript1.py $query");
ob_start();
$out=ob_get_contents();
echo print_r($out,true);
}
}
but i dont get any output on the browser. i tried returning it to a controller class and printing the output but it just wont work.any help wud be appreciated. is it an issue with cakephp? because the same application works fine in normal php.
Try moving ob_start() above $tmp=passthru("python serverscript1.py $query");. It appears nothing is being output after the output buffer is started.
<?php
class SearchCategorizationService
{
function searcher($query)
{
ob_start();
$tmp=passthru("python serverscript1.py $query");
$out=ob_get_contents();
echo print_r($out,true);
}
}
?>
I've the following super simple Zend Application:
Controller (IndexController.php):
public function indexAction()
{
$this->view->var_controller = "foo";
}
Layout (layout.phtml):
<?php
$var_layout;
echo $this->var_controller; ?> (1.)
When i set the breakpoint at echo output in layout script ("echo $this->var_controller") the breakpint is hit 2 times!
Does it mean the layuot script is executed 2 times or there is other explanation?
I have a php script the I often run using CLI (regular ssh terminal).
<?php
class foo {
public function __construct() {
echo("Hello world");
}
}
// script starts here...
$bar = new foo();
?>
When I run the code using php filename.php I get the Hello world stagnant as expected. Problem is that when i include the file from other php file I get the same thing (which I don't want).
How can I prevent code from running when file include but still use it as a CLI script?
You can test if $argv[0] == __FILE__ to see if the file called form the command line is the same as the included file.
class foo {
public function __construct() {
// Output Hello World if this file was called directly from the command line
// Edit: Probably need to use realpath() here as well..
if (isset($argv) && realpath($argv[0]) == __FILE__) {
echo("Hello world");
}
}
}
you can use php function get_included_files and check if your file is in array(using in_array)
http://php.net/manual/en/function.get-included-files.php
I hope this helps you.
You should check that you are BOTH running in the CLI environment AND NOT "included". See my re-write of your sample below:
<?php
class foo {
public function __construct() {
echo("Hello world");
}
}
// script starts here...
if (substr(php_sapi_name(), 0, 3) == 'cli'
&& basename($argv[0]) == basename(__FILE__) ) {
// this code will execute ONLY if the run from the CLI
// AND this file was not "included"
$bar = new foo();
}
?>