Get line and file where object is created in PHP - php

Is it possible to get the line and file where a object is created?
For example.
I know the print PHP error outputs where a error occurred and at which line. Is it possible to use that mechanism?
Sending the file to the object is easy. I can just use basename(__FILE__) as an argument. But I would prefer if the object arguments can remain empty. Like this:
Foo.php
<?php
class Foo {
public $line = null;
public function __construct(){
$this->line = where_object_is_assigned
}
}
?>
Index.php
<?php
$object = new Foo();
echo $object->line // Output Index.php line 3
?>
Is there a way for the object to access this data without sending it?
Thanks in advance

I solved it by using the function debug_backtrace();
<?php
class Foo {
public $line = null;
public function __construct(){
$bt = debug_backtrace();
$caller = array_shift($bt); // Get first array
$this->line = $caller["line"];
}
}
?>
Index.php
<?php
$object = new Foo();
echo $object->line // Output: 3
?>
The function must be used in __construct() else it won't work.
Read more here: http://php.net/manual/en/function.debug-backtrace.php

This will output on which line-number the object is created
Class
class Foo {
public $line = NULL;
public function __construct($line){
$this->line = $line;
}
}
Index.php
<?php
$object = new Foo(__LINE__); //Will output 1
echo $object->line;

PHP provides a large number of predefined constants to any script which it runs. Within this you can simply find the predefined constant named as LINE
__LINE__ The current line number of the file.
So you need to simply use the predefined constant within your code like as
<?php
class Foo {
public $line = __LINE__;
}
$object = new Foo();
echo $object->line;
?>

Related

Execute method in class dynamic using PHP 7.4

I would like to know how I can dynamically execute a method in my class using the following string.
$model = "Shop\Cart\Models\Cart#getInfo";
my idea is to save this command in the database, and then dynamically call the command and get the data return..
My difficulty is how to execute this command, is it possible?
An alternative I did is to explode the # and then use the call_user_func method, but I would like to know if there is any way without using explodes and making the request directly.
Define classname first
$className = 'Shop\Cart\Models\Cart';
Then call the method
(new $className())->getInfo();
You can make a function which can extract class and method name and call afterwards.
<?php
$model = "Cart#getInfo";
function make($str) {
$a = explode("#", $str);
$c = new $a[0];
return $c->{$a[1]}();
}
class Cart {
public function getInfo() {
return "Hello World";
}
}
$res = make($model);
print_r($res);
output
// Hello World
Try to use eval()
<?php
require_once './Classes/MyClasses.php';
function e($string)
{
$string = str_replace('#', '::', $string);
return eval($string . '();');
}
$a = e('Classes\MyClasses\MyClass#test'); // test
?>
file ./Classes/MyClasses.php contains next:
<?php
namespace Classes\MyClasses;
class MyClass
{
public static function test()
{
echo 'test';
}
}
?>

PHP calling class function dynamically by variables caughts exception

I'am trying to call a public funtion of a class with variables(php7). Therfore I do:
$module = 'frontend\\modules\\rest\\models\\Member';
$action = 'view_profile'
$response = new $module();
$response = $response1->$action;
By calling $response1->$action I get the following error:
Undefined property: frontend\modules\rest\models\Member::$view_profile
I see that the systems try to call ...Member\$view_profile and this will not work. But why is the '$' before view_profile. I've tried several variantes, but the error with the $view_profile is always there. What is wrong with this approach?
Check out this other reply: OOP in PHP: Class-function from a variable? (cannot comment, sorry...)
Anyway, this is what you are after: http://php.net/manual/en/functions.variable-functions.php
<?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()
?>
So I guess the only thing missing is the "()" after
$response1->$action;

Why my php class does not save it's property?

Consider this sample code
<?php
class MyAwesomeClass {
public $myawesomeproperty = 'test';
public function __construct() {
$self = new stdClass();
$self->myawesomeproperty = "hello guys!";
}
}
$test_obj = new MyAwesomeClass();
echo '<pre>';
var_export( $test_obj );
echo '</pre>';
?>
It's supposed to set "myawesomeproperty" to a new string so var_export shows "hello guys!" in the output.
What I'm actually getting is
MyAwesomeClass::__set_state(array(
'myawesomeproperty' => 'test',
))
Apparently the construct function does not save anything to actual object.
Why is this happening? What am I missing?
You're setting the property of a local variable called $self. If you want to change the object's property, use $this instead:
<?php
class MyAwesomeClass {
public $myawesomeproperty = 'test';
public function __construct() {
$this->myawesomeproperty = "hello guys!";
}
}
$test_obj = new MyAwesomeClass();
echo '<pre>';
var_export( $test_obj );
echo '</pre>';
?>
You are creating a different object ($self) inside the constructor. You aren't doing anything with it, so the object is removed from memory when php leaves the function scope.
To overwrite a property of the object attached to the current function scope, use $this->myawesomeproperty="Hello Guys";

How do I get the included elements during include in php?

I'd like to get the class/included variables/elements when I included a php file/class, somehow maybe I should try reflection to do that? If so, how?
For instance, I'd have a PHP class called foo.php:
<?php
class foo
{
public function bar()
{
return "foobar";
}
}
?>
then, in bar.php, I would like to:
<?php
class bar
{
public function foo()
{
$included_resources = include("foo.php"); // Notice, $included_resources is an array
if (($key = array_search("foo", $included_resources)) != false) // "foo" can be any variable or class name
return $included_resources[$key]->bar();
}
}
$helloworld = new bar();
echo $helloworld->foo();
?>
Result: a string value of "foobar" will be represented on the screen
First, store the declared variables in an array before including a file. Then do the include. Then store the declared variables in another array again. Then simply check the difference:
$declared_vars_before = get_defined_vars();
include 'another_file.php';
$declared_vars_after = get_defined_vars();
foreach ($declared_vars_after as $value) {
if (!in_array($value, $defined_vars_before)) {
echo $value . '<br>';
}
}
Same with classes, but use get_declared_classes instead of get_defined_vars.

Why function as array item in php class doesn't work

For example, I have such a code:
<?php
$A = array(
'echoSmth' => function(){
echo 'Smth';
}
);
$A['echoSmth'](); // 'Smth'
?>
It works fine!
But If $A is not just a variable, but a Class method - than this doesn't work:
<?php
class AA {
public $A = array(
'echoSmth' => function(){ // Parse Error here!
echo 'Smth';
}
);
}
// Fixed call:
$t = new AA();
$t->A['echoSmth']();
// no matter what call, because error occurs early - in describing of class
?>
Why doesn't it work?
It displays:
Parse error: syntax error, unexpected T_FUNCTION
P.S. Sorry, I've made some mistakes in the way I call the method, I was in hurry. But there's no matter how I call. Error ocurrs even if I just declare class, without calling
As far as I'm aware, you can't have anything dynamic when defining a class member, you can however set it dynamically as below. So basically, you can't do it for the same reason that you can't do this: public $A = functionname();
Also, your call signature was incorrect, I've fixed it in my example.
<?php
class AA {
public $A = array();
public function __construct() {
$a = function() {
echo 'Smth';
};
$this->A['echoSmth'] = $a;
}
}
$t = new AA();
$t->A['echoSmth']();
Alternatively, you could define the whole array within __construct(), containing the method (so basically shift your code).
I got this to work. Not sure why direct declaration is not permitted though.
class AA {
var $A;
public function __construct() {
$this->A = array(
'echoSmth' => function(){
echo 'Smth';
}
);
}
}
$t = new AA();
$t->A['echoSmth']();
EDIT: I also saw and corrected $t->$a first, but I needed to move the declaration as well to make it work.
well , it kinda works ...
<?php
class Bleh
{
public $f = array();
public function register( $name , $func )
{
$this->f[ $name ] = $func;
}
}
$foo = new Bleh;
$foo->register( 'bar' , function(){ echo 'foobar'; } );
$foo->f['bar']();
?>

Categories