Determine calling scope in PHP - php

Is there a way to determine the scope in which a function is called from inside the function itself? (Or method; I'll use function to mean either in the remainder of the post.)
What I do not want is to have to pass __FILE__ or __CLASS__ constants into the function. This information is available in stack traces, etc. so I know it's floating around somewhere, but I'd like to know how to introspect it at runtime without throwing exceptions.
If there are any performance particularities for a solution, I'd like to know about those as well.
There are two use-cases I'm interested in.
Determine which file / line / function called my function
Determine the class type that originated the function call
Basically what I want is this:
class util
{
public static function checkScope()
{
echo $magic_scope_stuff;
}
public static function blah()
{
util::checkScope();
}
}
util::checkScope(); // main, line 14
util::blah(); // class util, line 9

There's debug_backtrace() for that.
The resulting array gives you a call trace from the entry point until the invocation of debug_backtrace.

Related

how to nest a function inside an another function in php [duplicate]

In JavaScript nested functions are very useful: closures, private methods and what have you..
What are nested PHP functions for? Does anyone use them and what for?
Here's a small investigation I did
<?php
function outer( $msg ) {
function inner( $msg ) {
echo 'inner: '.$msg.' ';
}
echo 'outer: '.$msg.' ';
inner( $msg );
}
inner( 'test1' ); // Fatal error: Call to undefined function inner()
outer( 'test2' ); // outer: test2 inner: test2
inner( 'test3' ); // inner: test3
outer( 'test4' ); // Fatal error: Cannot redeclare inner()
If you are using PHP 5.3 you can get more JavaScript-like behaviour with an anonymous function:
<?php
function outer() {
$inner=function() {
echo "test\n";
};
$inner();
}
outer();
outer();
inner(); //PHP Fatal error: Call to undefined function inner()
$inner(); //PHP Fatal error: Function name must be a string
?>
Output:
test
test
There is none basically. I've always treated this as a side effect of the parser.
Eran Galperin is mistaken in thinking that these functions are somehow private. They are simply undeclared until outer() is run. They are also not privately scoped; they do pollute the global scope, albeit delayed. And as a callback, the outer callback could still only be called once. I still don't see how it's helpful to apply it on an array, which very likely calls the alias more than once.
The only 'real world' example I could dig up is this, which can only run once, and could be rewritten cleaner, IMO.
The only use I can think of, is for modules to call a [name]_include method, which sets several nested methods in the global space, combined with
if (!function_exists ('somefunc')) {
function somefunc() { }
}
checks.
PHP's OOP would obviously be a better choice :)
[Rewritten according to the comment by #PierredeLESPINAY.]
It's not just a side-effect at all, but actually a very useful feature for dynamically modifying the logic of your program. It's from the procedural PHP days, but can come in handy with OO architectures too, if you want to provide alternative implementations for certain standalone functions in the most straightforward way possible. (While OO is the better choice most of the time, it's an option, not a mandate, and some simple tasks don't need the extra cruft.)
For example, if you dynamically/conditionally load plugins from your framework, and want to make the life of the plugin authors super easy, you can provide default implementations for some critical functions the plugin didn't override:
<?php // Some framework module
function provide_defaults()
{
// Make sure a critical function exists:
if (!function_exists("tedious_plugin_callback"))
{
function tedious_plugin_callback()
{
// Complex code no plugin author ever bothers to customize... ;)
}
}
}
Functions defined within functions I can't see much use for but conditionally defined functions I can. For example:
if ($language == 'en') {
function cmp($a, $b) { /* sort by English word order */ }
} else if ($language == 'de') {
function cmp($a, $b) { /* sort by German word order; yes it's different */ }
} // etc
And then all your code needs to do is use the 'cmp' function in things like usort() calls so you don't litter language checks all over your code. Now I haven't done this but I can see arguments for doing it.
All the above being said, one might simply create a nested function to replace some localized, repetitive code within a function (that will only be used inside the parent function). An anonymous function is a perfect example of this.
Some might say just create private methods (or smaller code blocks) in a class, but that is muddying the waters when an ultra-specific task (which is exclusive to the parent) needs to be modularized, but not necessarily available to the rest of a class. The good news is if it turns out that you do need that function somewhere else, the fix is rather elementary (move the definition to a more central location).
Generally speaking, using JavaScript as the standard by which to evaluate other C based programming languages is a bad idea. JavaScript is definitely its own animal when compared to PHP, Python, Perl, C, C++, and Java. Of course, there are lots of general similarities, but the nitty, gritty details (reference JavaScript: The Definitive Guide, 6th Edition, Chapters 1-12), when paid attention to, make core JavaScript unique, beautiful, different, simple, and complex all at the same time. That's my two cents.
Just to be clear, I'm not saying nested functions are private. Just that nesting can help avoid clutter when something trivial needs to be modularized (and is only needed by the parent function).
All of my php is OO, but I do see a use for nested functions, particularly when your function is recursive and not necessarily an object. That is to say, it does not get called outside of the function it is nested in, but is recursive and subsequently needs to be a function.
There's little point in making a new method for the express use of a single other method. To me that's clumsy code and sort-of not the point of OO. If you're never going to call that function anywhere else, nest it.
In webservice calling we found it a much lower overhead (memory and speed) dynamically including in a nested fashion, individual functions over libraries full of 1000s of functions. The typical call stack might be between 5-10 calls deep only requiring linking a dozen 1-2kb files dynamically was better than including megabytes. This was done just by creating a small util function wrapping requires. The included functions become nested within the functions above the call stack. Consider it in contrast to classes full of 100s of functions that weren't required upon every webservice call but could also have used the inbuilt lazy loading features of php.
if you are in php 7 then see this:
This implementation will give you a clear idea about nested function.
Suppose we have three functions(too(), boo() and zoo()) nested in function foo().
boo() and zoo() have same named nested function xoo(). Now in this code I have commented out the rules of nested functions clearly.
function foo(){
echo 'foo() is called'.'<br>';
function too(){
echo 'foo()->too() is called'.'<br>';
}
function boo(){
echo 'foo()->boo() is called'.'<br>';
function xoo(){
echo 'foo()->boo()->xoo() is called'.'<br>';
}
function moo(){
echo 'foo()->boo()->moo() is called'.'<br>';
}
}
function zoo(){
echo 'foo()->zoo() is called'.'<br>';
function xoo(){ //same name as used in boo()->xoo();
echo 'zoo()->xoo() is called'.'<br>';
}
#we can use same name for nested function more than once
#but we can not call more than one of the parent function
}
}
/****************************************************************
* TO CALL A INNER FUNCTION YOU MUST CALL OUTER FUNCTIONS FIRST *
****************************************************************/
#xoo();//error: as we have to declare foo() first as xoo() is nested in foo()
function test1(){
echo '<b>test1:</b><br>';
foo(); //call foo()
too();
boo();
too(); // we can can a function twice
moo(); // moo() can be called as we have already called boo() and foo()
xoo(); // xoo() can be called as we have already called boo() and foo()
#zoo(); re-declaration error
//we cannont call zoo() because we have already called boo() and both of them have same named nested function xoo()
}
function test2(){
echo '<b>test2:</b><br>';
foo(); //call foo()
too();
#moo();
//we can not call moo() as the parent function boo() is not yet called
zoo();
xoo();
#boo(); re-declaration error
//we cannont call boo() because we have already called zoo() and both of them have same named nested function xoo()
}
Now if we call test1() the output will be this:
test1:
foo() is called
foo()->too() is called
foo()->boo() is called
foo()->too() is called
foo()->boo()->moo() is called
foo()->boo()->xoo() is called
if we call test2() the output will be this:
test2:
foo() is called
foo()->too() is called
foo()->zoo() is called
zoo()->xoo() is called
But we cannot call both text1() and test2() at same time to avoid re-declaration error
For those that suggest that there is no practical use of nested functions. Yes they have use and this is an example.
Imagine that I have a file called my_file.php which is used to get an ajax result out of. But what if there are times that you don't want to get the result through ajax but you want to include it twice in the same page without conflicts?
Lets say ajax file my_file.php :
<?php
// my_file.php used for ajax
$ajax_json_in = 10;
function calculations($a, $b)
{ $result = $a + $b;
return $result;
}
$new_result = $ajax_json_in * calculations(1, 2);
$ajax_json_out = $new_result;
?>
Below example includes the above file twice without conflict. You may not want to ajax call it, because there are cases that you need to include it straight in the HTML.
<?php
// include the above file my_file.php instead of ajaxing it
function result1
{
$ajax_json_in = 20;
include("my_file.php");
return $ajax_json_out;
}
function result2
{
$ajax_json_in = 20;
include("my_file.php");
return $ajax_json_out;
}
?>
Including the file makes the file's functions nested. The file is used both for ajax calls and inline includes !!!
So there is use in real life of nested functions.
Have a nice day.
I know this is an old post but fwiw I use nested functions to give a neat and tidy approach to a recursive call when I only need the functionality locally - e.g. for building hierarchical objects etc (obviously you need to be careful the parent function is only called once):
function main() {
// Some code
function addChildren ($parentVar) {
// Do something
if ($needsGrandChildren) addChildren ($childVar);
}
addChildren ($mainVar); // This call must be below nested func
// Some more code
}
A point of note in php compared with JS for instance is that the call to the nested function needs to be made after, i.e. below, the function declaration (compared with JS where the function call can be anywhere within the parent function
I have only really used this characteristic when it was useful to execute a small recursive function inside a primary, more categorical function, but didn't want to move it to a different file because it was fundamental to the behavior of a primary process. I realize there are other "best practice" ways of doing this, but I want to make sure my devs see that function every time they look at my parser, it's likely what they should modify anyway...
Nested functions are useful in Memoization (caching function results to improve performance).
<?php
function foo($arg1, $arg2) {
$cacheKey = "foo($arg1, $arg2)";
if (! getCachedValue($cacheKey)) {
function _foo($arg1, $arg2) {
// whatever
return $result;
}
$result = _foo($arg1, $arg2);
setCachedValue($cacheKey, $result);
}
return getCachedValue($cacheKey);
}
?>
Nested functions are useful if you want the nested function to utilize a variable that was declared within the parent function.
<?php
ParentFunc();
function ParentFunc()
{
$var = 5;
function NestedFunc()
{
global $var;
$var = $var + 5;
return $var;
};
echo NestedFunc()."<br>";
echo NestedFunc()."<br>";
echo NestedFunc()."<br>";
}
?>

How do I get the function name outside a function in PHP?

Is this possible?
Pseudo-code:
class MyClass
{
function myFunc1()
{
...
}
function myFunc2()
{
echo GET_FUNCTION_NAME($this->myFunc1)
}
}
Wanted output:
myFunc1
In the code above the GET_FUNCTION_NAME method/function/construct/whatever would give back the textual representation of the function name given as parameter.
So the main point would be to get the name of a function as a string from outside the function.
All the code I have found deals with giving a function name via a string (eg. specifying callback methods), but none of them mentions how to get that function name without manually writing it in a string (thus duplicating code in a string and making refactoring harder than needed).
OTOH from inside the function it is easy with eg. __FUNCTION__ variable, so I'm not looking for that.
EDIT
A typical use case would be any callback method.
One example where I confronted this problem is the set_error_handler() method where it awaits a callable as first parameter. The callable can be simplified as a string. The problem is that if I specify the function name as a string, any time in the future when I will do refactoring I will have to take extra care to search for the strings as well and do special handling of them otherwise wrong references will be left there.
Not to mention the principle that any name should be defined once and any other use should refer to that one.
If the problem is that You need to specify a callback not using a string, but the function symbol itself, You can do with a help of anonymous function:
class MyClass {
function call(callable $c) {
...
}
function mycallback() {
...
}
function dosomejob() {
$this->call(function() { $this->mycallback(); })
}
}
From point of view of Your refactoring tool, there's still call to function mycallback, it's not reffered as a string.

Method invocation in PHP

I have TestClass and a public method in it.
I am able to call the same method using :: operator like static method and using an object.
What are the advantages or use of static functions in PHP, if we able to call public functions without creating object of the same class?
<?php
class TestClass {
public function testMethod() {
echo 'Method called';
}
}
TestClass::testMethod();
$classObj = new TestClass();
$classObj->testMethod();
?>
In this case, there is no difference.
However, the point of static functions is to say that some functions don't need an instance of the class in order to be executed. It is possible to call functions statically even if they are not marked as static, but it is technically incorrect to do so. If you have error_reporting(E_ALL) set, it will give you a strict standards error.
This is not because the code won't work, but because it might not.
class TestClass {
private $name = 'Rakesh';
public function doSomething() {
echo "Hi there";
}
public function doSomethingElse() {
echo "Hi there " . $this->name;
}
}
You can call the first function statically and it will work fine. But if you call doSomethingElse statically, it won't work, because it tries to access $this, which is only possible if you have an object.
So we apply the static keyword to doSomething to let (a) PHP and (b) the programmer using the class know that it is possible to call it statically. It's a promise that it will work.
The assumption should be that, if it is not marked as static, you shouldn't call it statically.
PHP's strict standards errors are meant to make your code better, even if it already works. The documentation for the E_STRICT constant says:
Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code.
In low-level terms, a static function in PHP isn't much different than a member function. The only real difference is that $this isn't provided to a static function.
That means the use of the static keyword is mostly of semantic benefit, as it helps you define the architecture and intended behaviour of your classes.
With that said, you shouldn't abuse the semantics. PHP can (optionally) warn you about those kinds of mistakes, and you should always pay attention to such warnings. The language specification is there for a reason, and it's designed to work in certain ways. If you use static (or any other language feature) incorrectly, then it may not always work as you expect. Future PHP updates or configuration changes could break your code unexpectedly.
Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can).
For compatibility with PHP 4, if no visibility declaration is used, then the property or method will be treated as if it was declared as public.
Advantages are ...
1>Hash memory will not create ,hence no wastage of Memory (no memory leak problem)
2>
// This makes little sense
Math m = new Math();
int answer = m.sin(45);
// This would make more sense
int answer = Math.sin(45);
It's like a shortchut, one feature more of php. But, to access to their properties you must declare them like constants. For example:
<?php
class Math{
const pi=3.1416;
}
echo Math::pi;
?>

Exit PHP script w/o error

I have a PHP script that registers approximately 20 functions. Ideally it'd be loaded with require_once. I want make it so that even if somehow it does get loaded more than once, it wouldn't try to re-register the functions. I could wrap each declaration in !function_exists, but I'm wondering if there's a faster way. (Or do you think 20 calls to !function_exists is negligible?) I tried using exit but that causes an error. Is it possible to exit w/o throwing an error ?
if ( /* already loaded */ ) {
/* leave gracefully */
}
/* declare ~20 functions */
if (!defined('ALREADY_LOADED')) {
define('ALREADY_LOADED', true);
// rest of your code goes here
}
This checks to see if a constant ALREADY_LOADED is defined, and if it is not, it defines the constant and will do whatever else you want.
After it's been run once, the constant will be defined, and it will not run a second time.
I suggest using a more descriptive constant name than ALREADY_LOADED.
I think using OOP is the most practical way
Can be used as a class with static functions
class SimleClass{
public static function func1($arg){...}
}
use it
SimpeClass::func1($arg);
or sigleton
class SimleClass{
protected static $_instance=null;
private function __construct(){...}
public static function getInstance(){
if(is_null(self::$_instance)
self::$_instance=new SimpleClass();
return self::$_instance;
}
public function func1($arg){...}
}
use it
SimpleClass::getInstance()->func1($arg);
and how to connect it think itself
can use include_once
and can implement the autoloader class
function myClassLoader($className){
include_once "/lib/$className.php";
}
spl_autoload_register(myClassLoader);
=============================================================
for more concrete answer requires more data.
Perhaps your application, you can rearrange to get the more logical structure
If you as an author don't require it more then once, (or use require_once() consistantly) there shouldn't be a problem about re-registering functions.
As for exiting without an error, try die().
I would try not to redeclare functions in first step (here require more than once).
Doing 20x function_exists() does not cost anything, only some time writing and wrapping ;)
Perhaps you could try to use classes/methods instead.
function_exists is no bad.
You can write your php script files in the following manner.
/* file1.php */
if(!defined('FILE1')) {
define('FILE1', 1);
/////////////////////////
// PUT file contents here.
/////////////////////////
}// file.php finished.
Now you can include this file as many time as you want here and there. Nothing will be redefined again.

PHP create_function Instance variable - Unable to call anonymous function: Follow up

This is somewhat a follow up to a previous question - but I've distilled the question down and have the "works" vs. "doesn't work" cases narrowed down much more precisely.
My Goal:
I have a class MyClass that has an instance variable myFunction. Upon creating a MyClass object (instantiating), the constructor assigns the instance variable myFunction with the result of a call to create_function (where the code and args come from a db call).
Once this object of type MyClass is created (and stored as an instance variable of another class elsewhere) I want to be able to call myFunction (the instance variable anonymous function) from "anywhere" that I have the MyClass object.
Experimental Cases -- below is my highly simplified test code to illustrate what works vs. what doesn't (i.e. when the expected functionality breaks)
class MyClass extends AnotherClass {
public $myFunction;
function __construct() {
$functionCode = 'echo "NyanNyanNyan";';
$this->myFunction();
/*Now the following code works as expected if put in here for testing*/
$anonFunc = $this->myFunction;
$anonFunc(); //This call works just fine (echos to page)!
/*And if i make this call, it works too! */
self::TestCallAnon();
}
public function TestCallAnon() {
$anonFunc2 = $this->myFunction;
$anonFunc2();
}
}
However, if I do the following (in another file, it errors saying undefined function () in... within the Apache error log.
//I'm using Yii framework, and this is getting the user
//objects instance variable 'myClass'.
$object = Yii::app()->user->myClass;
$object->TestCallAnon(); // **FAILS**
or
$func = $object->myFunction;
$func(); // ** ALSO FAILS **
In addition, several variations of calls to call_user_func and call_user_func_array don't work.
If anyone is able to offer any insight or help that would be great :).
Thanks in advance!
You can't pass references to functions around in PHP like you can in for instance JavaScript.
call_user_func has limited functionality. You can use it like so:
class MyClass {
function func() {}
static function func() {}
}
function myfunc() {}
$i = new MyClass();
call_user_func("myfunc", $args);
call_user_func(array($i, "func"), $args);
call_user_func(array(MyClass, "staticFunc"), $args);
I ended up solving this issue via a workaround that ended up being a better choice anyways.
In the end I ended up having a static class that had a method to randomly return one of the possible identifiers, and then another method which accepted that identifier to build the anonymous function upon each class.
Slightly less elegant than I would like but it ends up working well.
Thanks to everyone for your efforts.

Categories