Snippet 1 works. Snippet 2 doesn't. Why?
1.
foo();
function foo()
{
// do soemething
}
2.
foo();
if(!function_exists("foo"))
{
function foo()
{
// do soemething
}
}
See http://www.php.net/manual/en/functions.user-defined.php:
Functions need not be defined before
they are referenced, except when a
function is conditionally defined [...]
Its definition must be processed prior
to being called.
You're trying to execute foo() before testing to see whether it's defined or not (and subsequently defining it)
if(!function_exists("foo"))
{
function foo()
{
// do soemething
}
}
foo();
Related
I'm kind of new to PHP so please excuse the simplicity of my question in case it was,
I have a function foo() that always returns true, now my question is that while I have only checked the true being of foo() and not called the foo() function directly, how possibly did it execute then?
And is only PHP like this or it is the same say in JavaScript?
$x = 10;
function foo() {
global $x;
if($x = 10) {
return true;
}
return false;
}
if(foo()) {
echo 'Done foo() function!';
} else {
echo 'Not done foo() function...';
}
you did called foo in if(foo()) this line. Essentially what you did in this line is called foo and checked its return value with if. If you want to check if foo function is executed or not you can keep a flag as global variable and and set it to true in the function somewhere like this
$foo_executed = false;
function foo (){
global $foo_executed;
// your code here
$foo_executed = true;
}
//execute foo
foo();
if ($foo_executed){
echo "foo executed";
}
This behavior is also common in other programming languages. You can follow this tutorial to learn more about functions. good luck!
https://www.youtube.com/watch?v=HvxQww-7NGA
Example 1: Here I expect that function hello must be in the global scope.
But as per my expectation it does not behave same.It does not put function hello into global scope. at run time php must put function hello into global scope. It says undefined function hello().
$fruit=true;
foo();
hello();
function foo()
{
echo "you are in the foo<br/>";
}
if($fruit)
{
function hello()
{
echo "you are in the hello<br/>";
}
}
Example 2 : Now as after example 1 , i supposed the below script must also work as example 1. i supposed it will give also error undefined function bar(). But now here it behave differently and execute bar.
foo();
bar();
function foo()
{
function bar()
{
echo "I don't exist until foo() is called.\n";
}
}
So i am unable to get the concept how php interpreter behave internally. How does it parse the program, and does it execute the step one by one , or whole program at once?
I quote a manual for you:
When a function is defined in a conditional manner .... Its definition must be processed prior to being called.
And more:
All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa.
Example One:
You do not define the function hello() until a part of the script has run, its in an IF and therefore does not get defined until after you attempt to call it
Like this you get no errors as the IF is run before the now defined funtion hello is called. And of corse either way it is in the GLOBAL scope. But your way it didnt exist anywhere until after you called it.
<?php
$fruit=true;
if($fruit)
{
function hello()
{
echo "you are in the hello<br/>";
}
}
foo();
hello();
function foo()
{
echo "you are in the foo<br/>";
}
Not sure if this is due to a module I have installed or not, I've tried to remove all the extensions I have but this still doesn't work:
//test1.php
if(defined("TEST1")) {
return;
}
define("TEST1",1);
function test() {}
//test2.php
if(defined("TEST1")) {
return;
}
define("TEST1",1);
function test() {}
//test.php
include_once('test1.php');
include_once('test2.php');
test();
Results in a duplicate definition error. It looks like other checks like function_exists will work, but it's a bit messier to use.
According to PHP documentation (http://php.net/manual/en/functions.user-defined.php):
Functions need not be defined before they are referenced, except when a function is conditionally defined
It means that if you don't put your test() function into conditional statement it will be defined BEFORE script execution start.
To allow referencing functions that are defined further in the code, PHP at first searches the file for function (classes, etc) definitions, then runs the code. So when you're doing your:
if(defined('TEST1')) return;
Te function already exists and dupplicate error is triggered. The solution is to put them in any conditional statement (it does not have to make sense) or even just in braces. Functions defined in that manner will not be defined before script execution and also you won't be able to use them befere they are defined. You can fix your code just by doing this:
//test1.php
if(defined("TEST1")) {
return;
}
define("TEST1",1);
{
function test() {}
}
//test2.php
if(defined("TEST1")) {
return;
}
define("TEST1",1);
{
function test() {}
}
//test.php
include_once('test1.php');
include_once('test2.php');
test();
To test the behavior you can play with that two code snippets. This one will work:
<?php
test();
function test() {
echo 'Hello world!';
}
But this will fail with undefined function:
<?php
test();
{
function test() {
echo 'Hello world!';
}
}
While this again will work:
<?php
{
function test() {
echo 'Hello world!';
}
}
test();
Try
//test1.php
if(!defined("TEST1")) {
define("TEST1",1);
function test() {}
}
//test2.php
if(!defined("TEST1")) {
define("TEST1",1);
function test() {}
}
//test.php
include_once('test1.php');
include_once('test2.php');
test();
I have following php code in basic.php. How can I determine if the method row() was called? When I write next <?php $basic->row(); ?> it shows something like this - the method was defined!
Example
$basic->container(); // container was called
$basic->container(); // when called again, i need show some warning - CONTAINER CAN BE PUT ONLY ONCE and using exit() for example
This is the solution what i need
public function container(){
static $container = false;
if ( $container ){ return; } else { print '<div class="container">'; } $container = true;
}
If you want to know if an object has a method or not before calling it, you can use method_exists.
if(method_exists($basic, 'row')) {
$basic->row();
}
Use the echo construct inside the row function like this:
// your code
function row(){
echo "Function called!";
....
}
This will print the text "Function called!" everytime you call the function.
I just add it as an answer ... try smthg like this:
function row(){
if($wascalled === true) {
echo "The function was called";
}
//your Code here
$wascalled = true;
}
So, the first time you call the function, nothing happens, if you call it more, the message will appear. It looks ugly and i dont see much sense in it, but it seems to work.
I did not understand if you mean really a call or if the method is defined.
As #Prasanth said, if you mean if the method is defined - method_exists will be a solution.
Otherwise, you can check my answer here: Cahining pattern
It's related to your problem, as you need a generic way to register a method been called before.
You, ofcourse, can write down
public $_row = false;
public function row() {
$this->_row = true;
// some stuff
}
and later:
if (!$basic->_row) {
$basic->row();
}
You just need a property where you will set a value, which corresponds to your script later. I.e. here the default value is false - it means the method hasn't been called yet. Once method is called, it changes it to true. You are testing if the value is default (false) then call.
You may not change the value to true, but to the string you wanted. E.g. $this->_row = 'the method was defined!' Or set to true and print the string, if $this->_row == true.
Reference
bool function_exists ( string $function_name )
Parameters The $function_name, as a string.
Returns TRUE if function_name exists and is a function, FALSE otherwise.
Note:
This function will return FALSE for constructs, such as include_once and echo.
<?php
if (function_exists('function_name')) {
echo "IMAP functions are available.<br />\n";
} else {
echo "IMAP functions are not available.<br />\n";
}
?>
Take this as an example
<?php
if (function_exists('foo')) {
print "foo defined\\n";
} else {
print "foo not defined\\n";
}
function foo() {}
if (function_exists('bar')) {
print "bar defined\\n";
} else {
print "defining bar\\n";
function bar() {}
}
print "calling bar\\n";
bar(); // ok to call function conditionally defined earlier
print "calling baz\\n";
baz(); // ok to call function unconditionally defined later
function baz() {}
qux(); // NOT ok to call function conditionally defined later
if (!function_exists('qux')) {
function qux() {}
}
?>
Prints:
foo defined
defining bar
calling bar
calling baz
PHP Fatal error: Call to undefined function qux()
Alternative method
You can use magic method __call.
class Basic{
function row(){
print ' Call method '.__METHOD__.'<br/>';
}
function __call($method,$params){
if (method_exists($this, $method)) {
call_user_func_array(array($this, $method), $params);
}else{
print 'Class '.__CLASS__.' hasn`t method "'.$method.'"<br/>';
}
}
}
$basic = new Basic();
$basic->row();
$basic->fetch();
// output
Call method Basic::row
Class Basic hasn`t method "fetch"
Is it possible to access outer local varialbe in a PHP sub-function?
In below code, I want to access variable $l in inner function bar. Declaring $l as global $l in bar doesn't work.
function foo()
{
$l = "xyz";
function bar()
{
echo $l;
}
bar();
}
foo();
You could probably use a Closure, to do just that...
Edit : took some time to remember the syntax, but here's what it would look like :
function foo()
{
$l = "xyz";
$bar = function () use ($l)
{
var_dump($l);
};
$bar();
}
foo();
And, running the script, you'd get :
$ php temp.php
string(3) "xyz"
A couple of note :
You must put a ; after the function's declaration !
You could use the variable by reference, with a & before it's name : use (& $l)
For more informations, as a reference, you can take a look at this page in the manual : Anonymous functions
You must use the use keyword.
$bar = function() use(&$l) {
};
$bar();
In the very very old PHP 5.2 and earlier this didn't work. The syntax you've got isn't a closure, but a definition of a global function.
function foo() { function bar() { } }
works the same as:
function foo() { include "file_with_function_bar.php"; }
If you execute function foo twice, PHP will complain that you've tried to re-define a (global) function bar.
You can read default value by:
function(){
return preg_match(
"yourVar = \d+"
, str_file_get_contents(functionFile)
, arrayToPutFieldsValue
);
}
If You would use two functons in the same time - it's like someone's using a spoon and You want to take a food from that spoon - You'll waste a food or some of You will starv.
Anyway - You would have to set a pointer somehow in a hard way.
It's impossible to get any field from other function or class without calling it to life.
Functions/methods are instance-like - they need to be called.
Share the common fields by accessing a global fields with synchronized functions.
function a()
{
function val1($arg=null)
{
static $a;
if ($arg !== null) $a = $arg;
else return $a;
}
function b()
{
val1('1234');
echo val1() . '<br>'; // shows: 1234
val1('my custom data');
echo val1() . '<br>'; // shows: my custom data
}
b();
}
a();
Used val1('my custom data') to set my value
Used val1() to get my value