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"
Related
How can I assign a function to a method in a class in PHP? I tried the following:
class Something{
public function __construct(){
$functionNames = array('foo', 'bar')
$variable = 'blablabla';
foreach($functionNames as $functionName){
if(method_exists($this, $functionName))
continue;
$this->{$functionName}() = function($params){ //should create the methods "foo" and "bar"
echo $variable; //should echo 'blablabla' (I know that the variable was declared outside this function, but how can I access it anyway?)
}; //the error points to here
}
}
}
But this code gives me this error:
Fatal error: Can't use method return value in write context
Does anyone know how I can assign the anonymous function to the class method, while also still being able to access variables outside that function?
You are doing foreach($functionNames as $functionName){ which means that $functionName is a string, not an array. So, don't use $functionName[0].
method_exists takes 2 parameters. One is the object and the other is the method name. It should be:
method_exists($this, $functionName)
As for creating the function, you don't need () on the left side of the =. It should be:
$this->$functionName = function($params) use($variable){
echo $variable;
};
The use($variable) is needed to tell PHP to use that variable inside the function. That's how closures work in PHP, it's different than other languages.
So, your class should look like:
class Something{
public function __construct(){
$functionNames = array('foo', 'bar');
$variable = 'blablabla';
foreach($functionNames as $functionName){
if(method_exists($this, $functionName)){
continue;
}
$this->$functionName = function($params) use($variable){
echo $variable;
};
}
}
}
Problem here is that in this way of making functions, you are not actually creating a class method, but instead creating a class variable that contains a function.
So, you need to call it like so:
$test = new Something;
$foo = $test->foo;
$foo('abc');
You can't just do $test->foo('abc');.
EDIT: Another thing you can do is use PHP's __call "magic method". This will be ran whenever you do ->funcName(), regardless of whether the method exists or not. Using that method, you can just check to see if the method called was 'foo' or 'bar'. See this example:
class Something{
private $variable;
public function __construct(){
$this->variable = 'blablabla';
}
public function __call($name, $params=array()){
if(method_exists($this, $name)){
// This makes sure methods that *do* exist continue to work
return call_user_func(array($this, $name), $params);
}
else{
$functionNames = array('foo', 'bar');
if(in_array($name, $functionNames)){
// You called ->foo() or ->bar(), so do something
// If you'd like you can call another method in the class
echo $this->variable;
}
}
}
}
With this, now you can do the following:
$test = new Something;
$test->foo('abc'); // Will echo "blablabla"
I would like to have an array of methods in my php class, indexed with method names, so that I can do something like this:
public function executeMethod($methodName){
$method=$this->methodArray[$methodName];
$this->$method();
// or some other way to call a method whose name is stored in variable $methodName
}
I've found this for __call:
The overloading methods are invoked when interacting with properties
or methods that have not been declared or are not visible in the
current scope
However, methods I'd like to use in executeMethod are visible.
What is proper way to do that? Is it possible?
EDIT: I wanted to get a method name in the executeMethod, and then call the method of the given name, and had an idea of methods array.
you can call object methods and properties by using string with syntax
$method = 'your_method_name_as_string';
$this->$method();
from php doc
<?php
class Foo
{
function Variable()
{
$name = 'Bar';
$this->$name(); // This calls the Bar() method
}
function Bar()
{
echo "This is Bar";
}
}
$foo = new Foo();
$funcname = "Variable";
$foo->$funcname(); // This calls $foo->Variable()
?>
Maybe you are looking for something like this:
public function executeMethod($methodName) {
if (isset($this->methodArray[$methodName])) {
$method = $this->methodArray[$methodName];
return call_user_func(array($this, $method));
}
throw new Exception("There is no such method!");
}
anonymous functions are available in php 5.3
i think you're trying to do something like
$tmp['doo'] = function() { echo "DOO"; };
$tmp['foo'] = function() { echo "FOO"; };
$tmp['goo'] = function() { echo "GOO"; };
$tmp['doo']();
Example code:
class MyClass {
function echo_msg {
echo // now what...
}
function echo_from_inside {
$this->echo_msg()
}
}
result should be:
$my_instance = new MyClass();
$my_instance->echo_msg(); // I was called from OUTside
$my_instance->echo_from_inside(); // I was called from INside
It might be easier, rather than detecting from whence the function was called, to wrap a private function with a public one. Like so:
class MyClass{
private function myob(){
//do something
}
public function echo_msg(){
$this->myob();
//do other stuff like set a flag since it was a public call
}
private function foo(){ //some other internal function
//do stuff and call myob
$this->myob();
}
}
$obj=new MyClass();
$obj->echo_msg();//get output
$obj->myob(); //throws error because method is private
You can try and get the caller of your method:
$trace = debug_backtrace();
$caller = array_shift($trace);
echo 'called by '.$caller['function']
echo 'called by '.$caller['class']
this should work for you.
You could add an optional parameter like such:
function echo_msg($ins=false) {
if($ins){/*called from inside*/}else{/*called from outside*/}
echo // now what...
}
and leave that last. If you are calling it from inside the class, pass it true, otherwise pass nothing!
1 function foo($i){
2 return bar($i)*4;
3 function bar($i){
4 return $i*4;
5 }
6 }
7 echo foo(4);
return
Fatal error: Call to undefined function bar() in /var/www/index.php on line 2
why doesn't it work? it works well in javascript, while it works when i do this:
function foo($i){
return bar($i)*4;
}
function bar($i){
return $i*4;
}
Define the function above your return value, otherwise it never gets executed.
<?php
function foo($i){
function bar($i){
return $i*4;
}
return bar($i)*4;
}
echo foo(4);
?>
It doesn't work as you are calling bar() before it has been created.
See example 2 here:- http://www.php.net/manual/en/functions.user-defined.php
Your code never reach function bar(...), therefore it's never defined.
You need to put your bar() function before your foo() or before the return bar. (Answer based on your first example).
With your second example you probably define bar() before you use foo() therefore bar() is defined and it works fine.
So as long as you have your function defined when you hit a certain spot in your code it works fine, no matter if it's called from within another function.
If you define function within another function, it can be accessed directly, but after calling parent function.
For example:
function a () {
function b() {
echo "I am b.";
}
echo "I am a.<br/>";
}
//b(); Fatal error: Call to undefined function b() in E:\..\func.php on line 8
a(); // Print I am a.
b(); // Print I am b.
Execution not execute after return statement
change your code like this
function foo($i){
function bar($i){
return $i*4;
}
return bar($i)*4;
}
echo foo(4);
For the sake of having a "recent" answer, here's what I did:
function printRx($conn, $patient)
{
function rows($rows, $tod)
{
for ($x = 0; $x < count($tod); $x++) {
if ($tod[$x] == 1) {
$rows++;
break;
}
}
return $rows;
}
$tod['prn'] = (explode('|', $row['prn'])) ?? null;
$rows = rows($rows, $tod['prn']);
return;
}
Works beautifully
Is it possible to add methods to functions?
For example:
<?
function func(){
;
}
//add method
func->test = function(){
;
}
func->test();
func();
I'm coming from a javascript background, and therefore I'm used to 'everything is an object'.
EDIT:
I was just explaining where the misconception may often come from for new phpers. I understand the above code doesn't work.
EDIT 2
Figured it out.
class myfunc_class{
function __invoke(){
//function body
}
function __call($closure, $args)
{
call_user_func_array($this->$closure, $args);
}
}
$func = new myfunc_class;
$func->test = function(){
echo '<br>test<br>';
};
$func->test();
$func();
Even sexier :)
class func{
public $_function;
function __invoke(){
return call_user_func_array($this->_function,func_get_args());
}
function __construct($fun){
$this->_function = $fun;
}
function __call($closure, $args)
{
call_user_func_array($this->$closure, $args);
}
}
$func = new func(function($value){
echo $value;
});
$func->method = function(){
echo '<br>test<br>';
};
$func('someValue');
$func->method();
No.
Not everything is an object in PHP. In fact the only thing that is an object is, well, an object. More specifically, and generally, an instantiation of a class.
Your code converted to PHP
// function_object.php
<?php
class FunctionObject {
public method func() {
// do stuff
}
}
?>
In other code you would use it like this:
<?php
// example.php in same folder as function_object.php
include 'function_object.php';
$FuncObj = new FunctionObject;
$FuncObj->func();
Also: read more about PHP & OOP
No, because an object is a different PHP language construct than a function. Functions do not have properties, but are instead simply execution instructions.
But, if func were instead a pre-defined class, then yes... with a bit of witchcraft, ignoring public outcry, foregoing readability and PHP coding standards, and by using closures with the __call() magic method...
class func
{
function __call($func, $args)
{
return call_user_func_array($this->$func, $args);
}
}
$obj = new func;
$obj->test = function($param1, $param2)
{
return $param1 + $param2;
};
echo $obj->test(1,1);
This won't work as you'd think without __call(), because by $obj->test(1,1), PHP thinks you're trying to call a non-existent method of func when out of object scope. But inside, being that the new "test" property is of a type: closure, the call_user_func_array() just sees the "test" property as just another function, so you can hide this bit of trickery from outside scope.
You would need your function func() to return an object, then you'd be able to do something like: func()->test();
But please note that your way of handling objects is not right in PHP and I suggest that you go read the OO documentations here.
In difference to javacript, in PHP not everything is an object. Therefore you need to differ between function and class.
If you want to create an object, you need to define the class first.
class myClass {
}
You can then add as many functions to the class as you need. But you need to define them first:
class myClass {
function test() {
echo "test!\n";
}
}
When everything is ready, you can bring it to life then:
$class = new myClass;
$class->test();
Checkout the manual for more.
You can't do what you're trying to do, but you can define functions inside of other functions.
This example outputs text:
function a() {
function b() { echo 'Hi'; }
}
a();
b();
Output: HiHi
This example outputs an error:
function a() {
function b() { echo 'Hi'; }
}
b();
Output: ERROR