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();
}
?>
Related
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
I am developing an app where I need to log the proccess.
So I was loggin from main.php and now I need to log from another class (class_TestingLog.php)
Next code is how I am trying. Could you tell me what I am doing wrong?
Thank you in advance.
main.php
[...]
#Logging class
include_once("./classes/class_log.php");
$Class_Log = New Class_Log();
#TestingLog Class
include_once("./classes/class_testingLog.php");
$Class_TestingLog = New Class_TestingLog();
[...]
$Class_Log->FreeLog("Test log");
$Class_TestingLog->AnyFuncion();`
[...]
class_log.php
[...]
public function FreeLog($text)
{
// echo $text . "\n"; #mistake
$this->outputText .= text; #correct one
}
[...]
class_testingLog.php
private $Class_Log = '';
[...]
public function __construct()
{
#Requires
require_once("./classes/class_log.php");
$this->Class_Log = New Class_Log();
}
public function AnyFuncion()
{
var_dump($this); #From real file
$this->Class_Log->FreeLog("Test log from another classs");
}
[...]
Browser output
Test log
Browser output expected
Test log
Test log from another classs
===========================================================================
EDIT
I made an error copying FreeLog();
It stores the parameter string value into a private variable instead echo the variable.
You require_once statement inside __construct for Class_TestingLog is invalid and unnecessary. As both files are in the same directory it should be "class_log.php" not "./classes/class_log.php". There is no need for it anyway, as when you include them both in main.php it is loaded already. So try it without the require_once.
EDIT: As discussed in chat do it like this:
in main.php:
$Class_TestingLog = New Class_TestingLog($Class_Log);
in class_testingLog.php:
public function __construct($ClassLog)
{
$this->Class_Log = $ClassLog;
}
This will use the same instance inside the Class_TestingLog class as on the main.php.
So I am running PHP 5.6 on my server and I am trying to check if a function exists, when I do I type this code.
<?php
$functionName = 'SalesWeek';
if (function_exists($functionName)) {
$functionName();
} else {
echo "No function exists for ".$functionName."\n";
}
function SalesWeek(){
echo "Hello!";
}
This fails every single time that I run it. But if I take that exact same code and drop it in something else i.e phptester.net it works just fine. I am using codeigniter so I thought maybe it had to do with that so I tried changing the function to public and private to see if it made a difference. Any ideas?
function_exists() only works for top-level functions, not object methods:
<?php
function foo() { echo "foo\n"; }
class bar { function baz() { echo "baz in bar\n"; }}
var_dump(function_exists('foo'));
var_dump(function_exists('baz'));
output:
bool(true) <--foo
bool(false) <--baz
Nor will it work for nested functions:
function x() {
function y() { ... }
}
var_dump(function_exists('y')) -> bool(false)
Technically functions (in the wild) are not methods (aka "function in a class").
function_exists() does not check for class methods. It checks only for functions in the namespace you are using.
If you want to check for a class' method you need to use method_exists() http://php.net/manual/en/function.method-exists.php
Also there is an order in php is read. And it is top-to-bottom. So in your example above the function you are looking for does not exists before you define it on the last 3 lines of your code.
**BELOW EXAMPLE IS NOT TRUE, SEE THE EDIT **
function_exists('myFunc'); //returns false
function myFunc(){}
function_exists('myFunc'); //returns true
Hope this clears things a bit
EDIT:
I just discovered a very strange behavior (PHP 5.6)
if the function is in the same file:
<?php
function_exists('myFunc'); //returns TRUE
function myFunc(){}
function_exists('myFunc'); //returns TRUE
if it's not in the same file:
<?php
echo function_exists('myFunc') ;//returns FALSE
include 'test2.php';//assume myfunc() is defined in this file
echo function_exists('myFunc');//returns TRUE
SO my first answer above seems to be only partially true.
PHP reads your code top to bottom, but it reads whole files. So if you define your function in the same file it will "exist" for php. If it's in another file, that file must first be loaded/included.
If you are using namespaces be sure to include the full qualified name:
function_exists('\myNameSpace\myFunctionName');
I want to ask the user to locate a folder on the (windows) commandline.
Usually you'll be able to use autocomplete with the [tab] key.
But not if I ask this from a phpscript.
I use this class:
<?php
class CLQuestion
{
protected $_awnser;
protected $_options;
protected $_question;
public function __construct($question, $options = array())
{
$this->_question = $question;
$this->_options = $options;
$this->askQuestion();
$this->waitForAwnser();
}
protected function askQuestion()
{
echo PHP_EOL . $this->_question . PHP_EOL;
}
protected function waitForAwnser()
{
while (true) {
$response = strtolower(trim(fgets(STDIN)));
// are options given?
if (empty($this->_options)) {
// no options given, so the response is our awnser
$this->_awnser = $response;
break;
} else if (!empty($this->_options) && in_array($response, $this->_options)) {
// options given and found in options
$this->_awnser = $response;
break;
} else {
// options given and not found.
echo PHP_EOL . 'Please use one of these options: ';
echo PHP_EOL . " " . implode(PHP_EOL . " ", $this->_options);
echo PHP_EOL;
continue;
}
}
}
public function getAwnser()
{
return $this->_awnser;
}
}
With this usage:
<?php
$question = new CLQuestion('Where is you folder located?');
$question->getAwnser(); // path typed
Windows CMD will give me a way to interact, but when i use the [tab] key, it does not autocomplete but it show a tab.
Am I able to activate path autocompletion in some way?
autocompletion is a feature of a windows shell prompt.
When you run an application like:
php script.php
this application gains control over STDIN and STDOUT and magic shell features like autocompletion will work no more until this app finishes.
This for example allows you to run one shell inside another.
If you need autocompletion in your script, you will need to implement it yourself. Instead of reading whole line with fgets(STDIN) you could read it char by char with fgetc(STDIN) and when the char will equal "\t" you would have to list files in current directory with php functions and check witch paths are matching to what user have written till now. So you will basically have to re-implement fgets adding magic autocompletion feature.
But instead of doing this and implementing your own shell I guess it would be far more better to make the folder location a script argument:
<?php
if(empty($argv[1])) die("usage: php script.php folderpath");
echo "your folder is located at:" . $argv[1];
So you could call it from windows shell like:
#php script.php
usage: php script.php folderpath
#php script.php foldername
your folder is located at: foldername
And then the autocompletion feature will work.
Is it possible to have return statements inside an included file that is inside a function in PHP?
I am looking to do this as I have lots of functions in separate files and they all have a large chunk of shared code at the top.
As in
function sync() {
include_once file.php;
echo "Test";
}
file.php:
...
return "Something";
At the moment the return something appears to break out of the include_once and not the sync function, is it possible for the included file's return to break out?
Sorry for the slightly odly worked question, hope I made it make sense.
Thanks,
You can return data from included file into calling file via return statement.
include.php
return array("code" => "007", "name => "James Bond");
file.php
$result = include_once "include.php";
var_dump("result);
But you cannot call return $something; and have it as return statement within calling script. return works only within current scope.
EDIT:
I am looking to do this as I have lots
of functions in separate files and
they all have a large chunk of shared
code at the top.
In this case why don't you put this "shared code" into separate functions instead -- that will do the job nicely as one of the purposes of having functions is to reuse your code in different places without writing it again.
return will not work, but you can use the output buffer if you are trying to echo some stuff in your include file and return it somewhere else;
function sync() {
ob_start();
include "file.php";
$output = ob_get_clean();
// now what ever you echoed in the file.php is inside the output variable
return $output;
}
I don't think it works like that. The include does not simply put the code in place, it also evaluates it. So the return means that your 'include' function call will return the value.
see also the part in the manual about this:
Handling Returns: It is possible to
execute a return() statement inside an
included file in order to terminate
processing in that file and return to
the script which called it.
The return statement returns the included file, and does not insert a "return" statement.
The manual has an example (example #5) that shows what 'return' does:
Simplified example:
return.php
<?php
$var = 'PHP';
return $var;
?>
testreturns.php
<?php
$foo = include 'return.php';
echo $foo; // prints 'PHP'
?>
I think you're expecting return to behave more like an exception than a return statement. Take the following code for example:
return.php:
return true;
?>
exception.php:
<?php
throw new exception();
?>
When you execute the following code:
<?php
function testReturn() {
echo 'Executing testReturn()...';
include_once('return.php');
echo 'testReturn() executed normally.';
}
function testException() {
echo 'Executing testException()...';
include_once('exception.php');
echo 'testException() executed normally.';
}
testReturn();
echo "\n\n";
try {
testException();
}
catch (exception $e) {}
?>
...you get the following output as a result:
Executing testReturn()...testReturn() executed normally.
Executing testException()...
If you do use the exception method, make sure to put your function call in a try...catch block - having exceptions flying all over the place is bad for business.
Rock'n'roll like this :
index.php
function foo() {
return (include 'bar.php');
}
print_r(foo());
bar.php
echo "I will call the police";
return array('WAWAWA', 'BABABA');
output
I will call the police
Array
(
[0] => WAWAWA
[1] => BABABA
)
just show me how
like this :
return (include 'bar.php');
Have a good day !