Get name function in PHP - php

I have some classes:
class A
{
private $_method;
public function __construct()
{
$this->_method = new B();
}
public function demo()
{
$this->_method->getNameFnc();
}
}
class B
{
public function getNameFnc()
{
echo __METHOD__;
}
}
I'm trying to get the function name of a class B class, but I want the function getNameFnc to return 'demo'. How do I get the name 'demo' in function getNameFnc of class B?

Well, if you really want to do this without passing a parameter*, you may use debug_backtrace():
→ Ideone.com
public function getNameFnc()
{
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
echo $backtrace[1]['function'];
}
* this would be the recommended way although one should never need to know which function has been previously called. If your application relies on that fact, you have got a major design flaw.

You will need to use debug_backtrace to get that information.
I haven't tested the code below but I think this should give you the information you want:
$callers = debug_backtrace();
echo $callers[1]['function'];

Why not pass it?
class A
{
private $_method;
public function __construct()
{
$this->_method = new B();
}
public function demo()
{
$this->_method->getNameFnc(__METHOD__);
}
}
class B
{
public function getNameFnc($method)
{
echo $method;
}
}
Or use __FUNCTION__ if you don't want the class name.

Related

How do I properly set method of derived class as callable for a parent class?

I am writing a basic class with some call_user_func() and then derived class with a method I want to be called from said call_user_func(). It looks as follows:
class Basic
{
private $InputHandler = null;
public function SetNewHandler(callable $NewHandler)
{
$this->InputHandler = $NewHandler;
}
public function ProcessInput()
{
call_user_func(array($this,$this->InputHandler));
}
}
class Specific extends Basic
{
public function Handler()
{
echo "Handler() is called\n";
}
}
$spec = new Specific();
$spec->SetNewHandler('Specific\Handler');
$spec->ProcessInput();
unset($spec);
Obviously it does not work since Specific\Handler is not recognized as a valid callable.
But what is the proper way to achieve this outcome? Parent class should be oblivious to the details of implementation of derived class and\or handler method.
I use php 7.4
I would just create a default handler method in the base class:
class Base
{
public function ProcessInput()
{
$this->Handler();
}
public function Handler()
{
// Some default code or just leave empty
echo "Base Handler() is called\n";
}
}
class Specific extends Base
{
public function Handler()
{
echo "Specific Handler() is called\n";
}
}
$spec = new Specific;
$spec->ProcessInput();
This way you don't need to manually bind the handler you want to use for each instance (which could be cumbersome). If you want a new handler, create a new class with that handler.
Here's a demo
If you made the call with call_user_func(array ($this, $this->InputHandler)); a method name is expected as the 2nd array element.
class Basic
{
private $InputHandler = null;
public function SetNewHandler($NewHandler)
{
$this->InputHandler = $NewHandler;
}
public function ProcessInput()
{
call_user_func(array($this,$this->InputHandler));
}
}
class Specific extends Basic
{
public function Handler()
{
echo "Handler() is called\n";
}
}
$spec = new Specific();
$spec->SetNewHandler('Handler');
$spec->ProcessInput();
Instead of call_user_func(Array($this, $this->InputHandler)); does this work here too:
$method = $this->InputHandler;
$this->$method();
or this:
$this->{$this->InputHandler}();
Alternatively: A callable is passed similarly as described by #Magnus Eriksson in the comment.
class Basic
{
private $InputHandler = null;
public function SetNewHandler(callable $NewHandler)
{
$this->InputHandler = $NewHandler;
}
public function ProcessInput()
{
call_user_func($this->InputHandler);
}
}
class Specific extends Basic
{
public function Handler()
{
echo "Handler() is called\n";
}
}
$spec = new Specific();
$spec->SetNewHandler([$spec,'Handler']);
$spec->ProcessInput();

Correct way of using polyporphism in php?

I'm new to object oriented php. And if there are no functions in the method testing() in the HumanClass, should i declare them as abstract?
<?php
class HumanClass
{
private $legs;
private $hands;
public function __construct($legs, $hands)
{
$this->legs = $legs;
$this->hands = $hands;
}
public function testing()
{
}
}
class StudentClass extends HumanClass
{
private $books;
public function __construct($legs, $hands, $books)
{
parent::__construct($legs, $hands);
$this->books = $books;
}
public function testing()
{
echo "StudentClass called.";
}
}
function callClass(HumanClass $c)
{
$c->testing();
}
$example = new StudentClass(4, 2, 1);
callClass($a);
?>
Is it possible to have something like this?
echo $a->testing();
instead of having another method to call testing().
Given the code that you give, it's far from clear what the testing() function is supposed to do other than just exist for you to try things. The answer to that will also determine whether the versions in the baseclass should remain there as empty function.
There are other options, too, e.g. that the derived class first invokes the baseclass (extending), or that the baseclass doesn't contain an abstract or concrete such function but only the derived one does. Which to choose is up to the informed programmer to decide.

php class call function within function

Could someone help me understand how I can make functions within class methods, that would allow me to do things like this:
$class->send->activation_email()
I've seen many APIs do this, so I've tried:
class MyClass
{
public function send()
{
function activation_email()
{
echo "success!";
}
}
}
Undefined property: MyClass::$send
Consider:
class emailSender()
{
function activation_email()
{
if (mail($this->to, $this->subj, $this->body)) {
print $this->msg;
}
}
class MyClass
{
var $send;
function __construct()
{
$this->send=new emailSender();
$this->send->msg="success!";
}
}
$obj=new MyClass();
$obj->send->activation_email();
You probably want to an instance of another class within your class. Make a variable inside your class like this:
$this->otherclass = new Otherclass();
In this case, you can call functions from your other class the following way:
$myClass->otherclass->otherClassFunction()
Someone had answered but deleted the post. This is along the lines of what I was hoping for, and it works as expected:
class MyClass {
public function send(){
echo "Sending: ";
return $this;
}
public function activation_email(){
echo "activation email.";
}
}
$myClass = new MyClass();
$myClass->send()->activation_email();
What you are referring to (shame on no one for noticing this, for shame) is called "method chaining". A lot of big frameworks do this. Consider this example of use:
echo $obj->setName('Mike')->convertMtoN()->getName();
// Echoes "Nike"
Cool.
But here is how it works:
class Example {
private $name = '';
public function setName($name) {
$this->name = $name;
// We return the object, so you can call it again.
return $this;
}
public function convertMtoN() {
// Let's do Caps first
$this->name = str_replace("M", "N", $this->name);
// Then lowercase
$this->name = str_replace("m", "n", $this->name);
// We return the object, keep working
return $this;
}
public function getName() {
return $this->name;
}
}
$name = new Example;
echo $name->setName('Mike')->convertMtoN()->getName();
Essentially, for each method that does not implicitly return a value, you simply return the object, allowing you to continue chaining.
Awesome, right?
PHP rocks (now, I know it has its faults, but with HHVM and process forking, it basically rocks [dude, you will get there]).
You can play with this here:
https://ideone.com/fMcQ9u

Can I call inherited parent method without a name in PHP?

Is there a way to call an inherited method, without specifying it's function name?
Something like:
class Child extends Parent {
function some_function(){
// magically inherit without naming the parent function
// it will call parent::some_function()
parent::inherit();
// other code
}
function another_function(){
// it will call parent::another_function()
$result = parent::inherit();
// other code
return $result;
}
}
I could think of a hack to do this using debug_backtrace(), get the last function where inherit() was called and access it's parent with the same function name. I was wondering if there's a nicer way instead of using debug functions which are clearly not meant for this.
You can use the magic __FUNCTION__ constant.
class A
{
function some_function()
{
echo 'called ' . __METHOD__;
}
}
class B extends A
{
function some_function()
{
call_user_func(array('parent', __FUNCTION__));
}
}
$b = new B;
$b->some_function(); // prints "called A::some_function"
Instead of
call_user_func(array('parent', __FUNCTION__));
you can also do
parent::{__FUNCTION__}();
Dirty, but:
class Adult {
function mummy(){
return 'Walk like an Egyptian';
}
function daddy(){
return 'Luke, I am your father';
}
}
class Child extends Adult {
function mummy(){
echo 'Mummy says: ';
$me = explode('::',__METHOD__)[1];
echo parent::$me();
}
function daddy(){
echo 'Daddy says: ';
$me = explode('::',__METHOD__)[1];
echo parent::$me();
}
}
$o = new Child();
$o->mummy();
$o->daddy();
EDIT
Actually giving you a parent method called inherit();
class Adult {
private function mummy(){
return 'Walk like an Egyptian';
}
private function daddy(){
return 'Luke, I am your father';
}
protected function inherit($method) {
$beneficiary = explode('::', $method)[1];
return $this->$beneficiary();
}
}
class Child extends Adult {
public function mummy() {
echo 'Mummy says: ',
parent::inherit(__METHOD__),
PHP_EOL;
}
public function daddy() {
echo 'Daddy says: ',
parent::inherit(__METHOD__),
PHP_EOL;
}
}
$o = new Child();
$o->mummy();
$o->daddy();
Dynamically calling functions:
static::$functionName();
In your case:
$func = __FUNCTION__;
parent::$func();
Note: the function name must be a string, if it's the actual function (not really relevant in this context) then it first needs to be converted to its string name first.
Other stuff that your question will probably lead you towards in the long run.
Check out late static binding it's what you're looking for.
Example taken from the linked page.
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // Here comes Late Static Bindings
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();

Calling a function within a Class method?

I have been trying to figure out how to go about doing this but I am not quite sure how.
Here is an example of what I am trying to do:
class test {
public newTest(){
function bigTest(){
//Big Test Here
}
function smallTest(){
//Small Test Here
}
}
public scoreTest(){
//Scoring code here;
}
}
Here is the part I am having problems with, how do I call bigTest()?
Try this one:
class test {
public function newTest(){
$this->bigTest();
$this->smallTest();
}
private function bigTest(){
//Big Test Here
}
private function smallTest(){
//Small Test Here
}
public function scoreTest(){
//Scoring code here;
}
}
$testObject = new test();
$testObject->newTest();
$testObject->scoreTest();
The sample you provided is not valid PHP and has a few issues:
public scoreTest() {
...
}
is not a proper function declaration -- you need to declare functions with the 'function' keyword.
The syntax should rather be:
public function scoreTest() {
...
}
Second, wrapping the bigTest() and smallTest() functions in public function() {} does not make them private — you should use the private keyword on both of these individually:
class test () {
public function newTest(){
$this->bigTest();
$this->smallTest();
}
private function bigTest(){
//Big Test Here
}
private function smallTest(){
//Small Test Here
}
public function scoreTest(){
//Scoring code here;
}
}
Also, it is convention to capitalize class names in class declarations ('Test').
Hope that helps.
class test {
public newTest(){
$this->bigTest();
$this->smallTest();
}
private function bigTest(){
//Big Test Here
}
private function smallTest(){
//Small Test Here
}
public scoreTest(){
//Scoring code here;
}
}
I think you are searching for something like this one.
class test {
private $str = NULL;
public function newTest(){
$this->str .= 'function "newTest" called, ';
return $this;
}
public function bigTest(){
return $this->str . ' function "bigTest" called,';
}
public function smallTest(){
return $this->str . ' function "smallTest" called,';
}
public function scoreTest(){
return $this->str . ' function "scoreTest" called,';
}
}
$test = new test;
echo $test->newTest()->bigTest();
To call any method of an object instantiated from a class (with statement new), you need to "point" to it. From the outside you just use the resource created by the new statement.
Inside any object PHP created by new, saves the same resource into the $this variable.
So, inside a class you MUST point to the method by $this.
In your class, to call smallTest from inside the class, you must tell PHP which of all the objects created by the new statement you want to execute, just write:
$this->smallTest();
In order to have a "function within a function", if I understand what you're asking, you need PHP 5.3, where you can take advantage of the new Closure feature.
So you could have:
public function newTest() {
$bigTest = function() {
//Big Test Here
}
}
class sampleClass
{
public function f1()
{
return "f1 run";
}
public function f2()
{
echo ("f2 run" );
$result = $this->f1();
echo ($result);
}
f2();
}
output :
f2 run
f1 run
You need to call newTest to make the functions declared inside that method “visible” (see Functions within functions). But that are then just normal functions and no methods.
example 1
class TestClass{
public function __call($name,$arg){
call_user_func($name,$arg);
}
}
class test {
public function newTest(){
function bigTest(){
echo 'Big Test Here';
}
function smallTest(){
echo 'Small Test Here';
}
$obj=new TestClass;
return $obj;
}
}
$rentry=new test;
$rentry->newTest()->bigTest();
example2
class test {
public function newTest($method_name){
function bigTest(){
echo 'Big Test Here';
}
function smallTest(){
echo 'Small Test Here';
}
if(function_exists( $method_name)){
call_user_func($method_name);
}
else{
echo 'method not exists';
}
}
}
$obj=new test;
$obj->newTest('bigTest')
You can also use self::CONST instead of $this->CONST if you want to call a static variable or function of the current class.

Categories