Welcome Guest ( Log In | Register )

Outline · [ Standard ] · Linear+

PHP How can I call a function like a method?

views
     
TSeek-1
post Apr 1 2014, 03:43 AM, updated 10y ago

Custom member title
*****
Senior Member
776 posts

Joined: Jan 2003
From: Polysiloxanes Boulevard



For instance I have a function:

function hello($name='') { echo "hello $name"; }


This function is not in any particular class. I can call it by just typing in hello();
But I'd like to also "put" it into a dumb class as a method just so I can call it, like so:

$class = new simpleClassForThePurposeOfPuttingUserFunctionsInIt;

registerFunctionIntoAClassAsAMethod('hello',$class);

$class->hello('Johan');

How do I define the class and how to code the registerFunctionIntoAClassAsAMethod($functionName,&$theClass) ?

This post has been edited by eek-1: Apr 1 2014, 03:48 AM
Zepx
post Apr 1 2014, 10:44 AM

Regular
******
Senior Member
1,232 posts

Joined: Dec 2005
Well, I am not exactly sure if I got your question, but there is no straightforward way of doing this.

You need to have your class support the magic method __call()

CODE

class MyClass {
  private $funcMap = array();
 
  function registerMethod($funcName, $func = null) {
     is_null($func) ? $this->funcMap[$funcName] = $funcName : $this->funcMap[$funcName] = $func;
  }
 
  function __call($name, $args) {
     return call_user_func_array($this->funcMap[$name], $args);
  }
}


Assuming you have PHP 5.3 which supports anonymous functions, you could do something like that:

CODE

//Anonymous Function
$myFunc = function($yourName) {
  echo "Hello $yourName!";
};

//Normal Function
function anotherFunc($yourName) {
  echo "Hey there $yourName!";
}

$myObj = new MyClass();
$myObj->registerMethod("sayHello", $myFunc);
$myObj->sayHello("Zepx");

$myObj->registerMethod("anotherFunc");
$myObj->anotherFunc("John");


Do note though such method merely hides the function in the object but does not entitle it to the object instance variables such as $this.

This post has been edited by Zepx: Apr 1 2014, 10:44 AM
M_Shahrul
post Apr 1 2014, 04:26 PM

On my way
****
Senior Member
635 posts

Joined: Apr 2010
From: Kuala Lumpur


Dude, for sure use a basic and simple PHP object oriented method...

CODE
class MyClass
{
    public $prop1 = "I'm a class property!";

    public function setProperty($newval)
    {
        $this->prop1 = $newval;
    }

    public function getProperty()
    {
        return $this->prop1 . "<br />";
    }
}

$obj = new MyClass;

echo $obj->prop1;


This post has been edited by M_Shahrul: Apr 1 2014, 04:26 PM
TSeek-1
post Apr 1 2014, 11:05 PM

Custom member title
*****
Senior Member
776 posts

Joined: Jan 2003
From: Polysiloxanes Boulevard



QUOTE(Zepx @ Apr 1 2014, 10:44 AM)
You need to have your class support the magic method __call()

Assuming you have PHP 5.3 which supports anonymous functions, you could do something like that:

Do note though such method merely hides the function in the object but does not entitle it to the object instance variables such as $this.
*
Thanks a lot, will try this later on.


QUOTE(M_Shahrul @ Apr 1 2014, 04:26 PM)
Dude, for sure use a basic and simple PHP object oriented method...
*
There are reasons that I had to do it my way. One is to save time and effort from having to rewrite legacy codes.
silverhawk
post Apr 3 2014, 03:41 AM

I'm Positively Lustrous
Group Icon
Elite
4,738 posts

Joined: Jan 2003


I'm rather curious what sort of legacy code you have that you have to resort to doing something like this. Mind sharing?


TSeek-1
post Apr 7 2014, 03:03 AM

Custom member title
*****
Senior Member
776 posts

Joined: Jan 2003
From: Polysiloxanes Boulevard



QUOTE(silverhawk @ Apr 3 2014, 03:41 AM)
Mind sharing?
*
The ~4 year old product I'm maintaining consists of client(s) - soap - service - db

Currently it only uses soap as the bridge to webservice. Now I'm making a new bridge that does simply without protocol, since soap has been useless to most customers. And since there are thousands of $soap->someFunction($parms) in client side, and there are a few different client apps, and for backward compatibility I rather avoid doing those.

This post has been edited by eek-1: Apr 7 2014, 03:05 AM
silverhawk
post Apr 7 2014, 12:34 PM

I'm Positively Lustrous
Group Icon
Elite
4,738 posts

Joined: Jan 2003


Couldn't you just make an adapter? Something like this

CODE

class SoapAdapter extends Soap {
   protected $_newBridge;

   public function __construct($newBridge) {
       $this->_newBridge = $newBridge;
   }

   public function someFunction($parms) {
       $this->_newBridge($parms, $maybeSomeOtherParamYouWant2Pass);
   }
}


This way you maintain the external interface for the soap calls, but internally its handled by your new bridge.
TSeek-1
post Apr 7 2014, 03:36 PM

Custom member title
*****
Senior Member
776 posts

Joined: Jan 2003
From: Polysiloxanes Boulevard



QUOTE(silverhawk @ Apr 7 2014, 12:34 PM)
Couldn't you just make an adapter? Something like this
*
Which class should I extend, SoapServer or SoapClient?
silverhawk
post Apr 7 2014, 06:31 PM

I'm Positively Lustrous
Group Icon
Elite
4,738 posts

Joined: Jan 2003


QUOTE(eek-1 @ Apr 7 2014, 03:36 PM)
Which class should I extend, SoapServer or SoapClient?
*
Whichever your new bridge is being adapted to. You would likely have to extend both. Can't say much without seeing your code or knowing the responsibilities of the class you're creating.
TSeek-1
post Apr 17 2014, 04:29 PM

Custom member title
*****
Senior Member
776 posts

Joined: Jan 2003
From: Polysiloxanes Boulevard



QUOTE
Can't say much without seeing your code
I know I should had explain more.

But anyway I solved it by aliasing.

CODE

// The new bridge; this call functions straightforward
class Direct
{
// Thanks for mentioning __call() Zepx
function __call($fName,$args) { return call_user_func_array($fName,$args); }
function add($fName) { /* Does nothing */ }
// some other functions to emulate soapserver & client
}



// Webservice side
use Direct as SoapServer;
function hello($a,$b) { echo "Hello {$a} {$b}"; }
$svr=new SoapServer('some configs');
$svr->add('hello');


// Client-side
use Direct as SoapServer;
$cli=new SoapClient('login credentials');
$cli->hello('Johan','Zizan');


 

Change to:
| Lo-Fi Version
0.0176sec    0.49    5 queries    GZIP Disabled
Time is now: 29th March 2024 - 05:43 PM