3

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();
2
  • Not all readers here are able to deal with a certain degree of abstraction and exemplary descriptions. However I found your question well understandable. Commented Jun 21, 2011 at 1:22
  • JavaScript's object handling is prototype based. This is different to almost every other popular programming language. If JavaScript is the only language you know, then I'm sorry, but you have some unlearning to do. Commented Jun 21, 2011 at 1:26

5 Answers 5

3

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

Sign up to request clarification or add additional context in comments.

3 Comments

Is there anyway to define a constant containing a instantiation of a class?
@Lime I haven't actually tried that but I would almost be willing to say 'Hell no'. I'm also willing to bet that constants must be only scalar values (normally you see strings or integers)
@Lime: No. See the link to the manual in my answer it references all the basic parts of the language incl. constants.
1

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.

7 Comments

I ended up refactoring you code slightly to get what I was looking for. Feel free to check my edit. Thanks.
@Lime: Disclaimer: Don't quote me on this, but I believe IDE's likely can't be made to work with closures. Also, this makes code readability and debugging a nightmare, especially if you're not the only one developing this library. But if that's not an issue, then nothing to worry about.
Why does it make debugging an issue? Alos, If you shouldn't use __invoke why is it continually supported in php?
What if I simply add my functions to the original class and remove the __call function entirely? Would you consider that more readable and digestible?
@Lime: Nothing wrong with __invoke(). But with closures/anon functions, it makes it difficult to track down where exactly the function was defined (or overwritten). It also makes it difficult to maintain organized libraries when you don't adhere to the coding standards of defining real, reusable function or class definitions.
|
0

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.

2 Comments

What do you mean by 'not right'. I was just trying to avoid polluting the global namespace.
@Lime In PHP your code needs to know the structure of an object (the class) before loading it, so you need to "pollute" the namespace. What you can do, if you use PHP 5.3, is to use custom namespaces if you are a clean freak.
0

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.

Comments

0

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

1 Comment

You'd need to call b() within a() after declaring it for this to work :) Also, if you call a() it should define b(), so you could do a();b(); but not b();a(); .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.