I am trying to understand about the closure class, at the manual there is,
All at the manual Link,
Closure::__construct - Constructor that disallows instantiation. If i understand it right the only instance of this class is for anonymous function variable assignment.
But i did not understand few lines:
Closure::bind — Duplicates a closure with a specific bound object and class scope.
Closure::bindTo — Duplicates the closure with a new bound object and class scope.
And the last at the manual i did not understand this sentence:
Besides the methods listed here, this class also has an __invoke
method. This is for consistency with other classes that implement
calling magic, as this method is not used for calling the function.
If can some one please try to explain thoes lines to me i will be very thankful, Have a nice day.
It is referring to the calling magic.
As my understanding, for any class that contains the method __invoke which its instances can be called as if it is a function. The Closure::__invoke acts like that.
i.e. when $foo is of class Closure (anonymous function), calling $foo($bar) will call $foo->__invoke(bar) (although the __invoke member is not meant to be called directly, this is just to show how it works).
When you define anonymous functions, you do this:
$greet = function($name)
{
printf("Hello %s\r\n", $name);
};
Now, $greet is of class Closure. and $greet->__invoke is sort of equal to function($name){ printf("Hello %s\r\n", $name); }
And remember, Closure::__invoke is a Magic Method.
I think the difference between bind and bindTo is just in the way they're called:
$cl->bindTo($obj)
is equivalent to
Closure::bind($cl, $obj)
Regarding the __invoke meethod, it's saying that the method exists, but it's not actually used. When you use the closure as a function, an internal (probably more efficient) mechanism is used that bypasses the method. But the method is there for compatibility with other classes that are callable, and you could call it manually if you wanted to.
Related
I understand that static methods have no access to state of instance objects of their class types and hence referencing $this inside them results in an error.But objects can reference static methods using object to member operator ->
$obj->staticMethod();
and can even pass it their state via paramaters.
$para1 = $obj->para1;
$para2 = $obj->para2;
$obj->staticMethod($para1, $para2);
How is this last example possible when statics are resolved in static context. If someone can explain to me the general behaviour of statics in php code. you can even talk about C related concepts if it will help.
Since you state that you already understand what static means, I'll skip over that.
However, it may still be good to reference PHP's documentation on the static keyword. In particular the following two alerts are important (and hard to glance over, really).
Caution In PHP 5, calling non-static methods statically generates an E_STRICT level warning.
And this one (italic emphasis mine).
Warning In PHP 7, calling non-static methods statically is deprecated, and will generate an E_DEPRECATED warning. Support for calling non-static methods statically may be removed in the future.
So, to cut a long story short: yes, your example will run (for now), because the PHP interpreter will try to fix up your mistake for you. You should however never do this. What the PHP interpreter will do is:
Say your $obj is of type Foo. Then it will read
$obj->staticMethod($para1, $para2);
conclude that staticMethod is static and instead execute
Foo::staticMethod($para1, $para2);
It is of course perfectly fine to pass parameters that are properties of an instance of Foo. It doesn't matter to staticMethod where the parameters come from.
To elaborate a bit more on why this works, while using $this in a static method is not allowed.
You can think of normal methods as static functions that have one extra: they receive an implicit parameter $this. The value of $this is simply the object on which the method is called. Thus, $obj->do($a, $b, $c) is equivalent to calling Foo::do($obj, $a, $b, $c) and naming the first argument of do, $this. This is convenient, because we can now easily define methods that work on an instance of an object without having to explicitly state over and over again that this instance is a parameter of our methods. Great.
Now back to static functions. The only difference with normal methods is that they do not receive this implicit $this parameter. Thus, using $this inside of them is invalid. Not because it is forbidden, but because it does not reference anything. PHP does not (and cannot) have a clue what $this should refer to.
Another way to look at it. Say that our Foo class has two properties: $para1 and $para2, both numbers. Say that you write a method that returns the sum of these numbers. One way is to do this:
public static function sum($para1, $para2) {
return $para1 + $para2;
}
Great. Works. However, it is annoying to have to call it like this
$sum = Foo::sum($obj->para1, $obj->para2);
So, this is what methods are for!
public function sum(/* implicit $this parameter */) {
// write looking up the properties once inside the function, instead
// of having to write it every time we call the function!
return $this->para1 + $this->para2;
}
// ...
$sum = $obj->sum(); // $obj is passed implicitly as $this
Because static functions do not receive an implicit $this parameter, using $this inside of them is like trying to use $undefined when you have never defined it. Thus, invalid.
Static means class members in simple terms , A static data member is accessible within a class regardless object is created or not . The static function are also functions dedicated to whole class . Static function works with static data only bit it can sometimes vary . Though statics are class dedicated, you can access them using object. It is allowed in all languages. Why ? Because of feasibility . If an object is not being able to access static members , that is a limitation.
I am confused about how "static" and "dynamic" functions and objects in PHP work together especially with regards to __callStatic().
How __callStatic() works:
You can have a normal class MyClass, where within the class you can
put a static function called __callStatic(), which gets called only
when MyClass doesn't have a static function by the name you want.
i.e. I call MyClass::newFunction();
newFunction() is called statically but MyClass does not
have it declared. So, then __callStatic() gets called and
inside you can say
$myObject=new SomeOtherClass();
$myObject->newFunction();
which calls the function you wanted but on some other object.
Short Version:
In other words, __callStatic() does this:
MyClass::newFunction();
which is hiding this:
(new SomeOtherClass())->newFunction();
Say what now? What looks like code calling a static function from a class, turns out to be calling that function from some other class and calling it via instantiation, and not statically.
Explain this, please!
Why was it done? Can you do anything like this elsewhere, like C++ or Java? I am looking for short & concise, but informative explanation on static and dynamic functions in languages, and in this case whether __callStatic() violates or conforms to the big picture of Language constructs. Or is it a new language construct entirely.
__callStatic() provides developers with possibility to react on static method calls even if that methods don't exist or aren't accessible from outside of the class ( being protected). This is useful for dynamic, generic code generation.
Example: You have this class:
class Test {
protected static function myProtected($test) {
var_dump(__METHOD__, $test);
}
public static function __callStatic($method, $args) {
switch($method) {
case 'foo' :
echo 'You have called foo()';
var_dump($args);
break;
case 'helloWorld':
echo 'Hello ' . $args[0];
break;
case 'myProtected':
return call_user_func_array(
array(get_called_class(), 'myProtected'),
$args
);
break;
}
}
}
Try to call:
// these ones does not *really* exist
Test::foo('bar');
Test::helloWorld('hek2mgl');
// this one wouldn't be accessible
Test::myProtected('foo');
Why was it done?
This is an existential question, but I think that the answer is "because you can". PHP is a dynamic language and these constructs __call and __callStatic() show off its power, and this power can be useful in some situations.
Can you do anything like this elsewhere, like C++ or Java?
No. They have no similar magic methods.
I am looking for short & concise, but informative explanation on static and dynamic functions in languages
Static functions encapsulate code. They exist even when no class has been instantiated. You can call them using scope resolution operator.
Dynamic functions are well, dynamic
.. does __callStatic() violate or conform to the big picture of Language constructs. Or is it a new language construct entirely.
It is a construct of a dynamic language. Not sure if this functionality exists in all dynamic languages, but it does in PHP. It does not violate anything, just introduces new paradigm of fall-through catch-all functions when the function you do call does not exist/not accessible in current scope.
I'm not entirely sure why __callStatic() is relevant here?
I don't quite see the difference between:
class Foo {
static function bar() {
$obj = new Foo();
$obj->quux();
}
function quux() {
return "whatever";
}
}
and your example? In both scenarios you're calling a static method which is calling another method on an object of the same class.
Yeah, that's possible. Actually doing it suggests you might want to refactor your code though. In the example you're instantiating an object with its default state, executing a method on it and then throwing the object away. This suggests whatever the method is doing doesn't actually need the objects state. That means it either doesn't belong in this class or could simply be rewritten to be a static method itself.
And are you aware of __call? It does the same thing as __callStatic but for objects rather than classes. E.g. $foo->myMissingMethod(); would go to __call if such a method exists for the class of which $foo is an instance.
I'm using both the magic methods _call and _callStatic for my own implementation of something like an ORM/Activerow. They're mainly meant for catching certain function calls: __call is responsible for getters and setters, and __callStatic for findBy methods (e.g. findById).
To map foreign keys, i'm trying to convert calls to e.g. getArticle to return the value of Article::findById(). To do that, i'm using this case inside my __call:
if (strstr($property, "_id")) {
return $foreignClass::findById($this->getId());
}
where $property is the substring after set or get in __call, and $foreignClass the rest of the string. So, in the case of the call getArticle, $property would be get and $foreignClass would be Article.
I've placed some echoes to ensure that the values are correct. However, my __call method gets called instead of my __callStatic. If i make an implicit static method findById, it does get called (so it does recognize it as a static call). If i specifically call Article::findById(), __call also catches it.
Is this an error with the relatively new __callStatic, or am i doing something wrong?
EDIT:
The problem seems to reside in this part:
_call() is triggered when invoking inaccessible methods in an object context.
__callStatic() is triggered when invoking inaccessible methods in a static context.
Though i am calling it on a class, i am calling it from an object context. Is there a way to get into the static context in this case?
Since the code you give runs in the context of an Activity object and since the value of $foreignClas is Article, which is an ancestor of Activity, PHP assumes that you are intending to call an ancestor's implementation of the method.
To break out of the object context there is AFAIK no option other than this absolutely hideous technique:
$id = $this->getById();
return call_user_func(
function() use($foreignClass, $id) {
return call_user_func("$foreignClass::findById", $id);
}
);
The __callStatic magic method was only introduced in PHP 5.3. Prior to that, I believe static calls were routed through __call just like normal method calls. My guess would be that you are using a PHP version that is < 5.3. What is the output of php -v on the command line?
With learning fuelPHP, I am introduced on calling classes using scope resolution, or :: in sense. Typically, when we call a method in a class we do this ...
$myclass = new myclass();
$myclass->mymethod();
On fuel, methods are usually called in this manner ...
myclass::mymethod();
I was wondering if there are any difference between the two? Is the scope resolution is something of an update on 5.3 as well ... if not, which one is ideal, or when should I use these.
Thanks.
The scope resolution operator is used to access either class constants like ::const, static variables like ::$var or call static methods like ::method().
See http://php.net/manual/en/language.oop5.static.php
Static methods can be called without having an instance of the class they are defined in. They're defined in that class with the static keyword.
For example, one of CakePHP's static methods is defined like this:
class ClassRegistry {
// ...
public static function &getInstance() {
// ...
}
}
... which you can call like ClassRegistry::getInstance().
Without the static keyword, you'd need an instance of the ClassRegistry class to call that function.
You can read more here, especially about why using static methods in your own code can sometimes be a bad idea: http://kore-nordmann.de/blog/0103_static_considered_harmful.html
I am not sure how would myclass::mymethod(); work, since I use such syntax only when I am calling a STATIC class.
MyClass::DoSomething();
would call a static method named DoSomething()
while
$instance = new MyClass();
$instance->DoSomething();
would call the instance method.
I have not tested it but I believe you will run into an error if you do $instance::DoSomething()
I think the best way to understand why there is a static call and what it does behind the scene is to check this FuelPHP blog's entry: http://fuelphp.com/blog/2011/05/why-did-you-do-that
The obvious difference is that the first solution $myObject->myMethod() it's a dynamic call : you need an instance to execute myMethod().
In the second solution, MyClass::myMethod() is a static call. The class acts as a sort of namespace where a function belong. You don't need an instance for that.
What is better to use in this context, static methods, or simple public method and call them always like this: $request = new Request();
if($request->isPostRequest()){ do smth }
ofcourse its easier to use static, but what is more properly to use?
Class Request {
public static function isSecureConnection() {}
public static function isPostRequest() {}
public static function isAjaxRequest() {}
...etc
}
If each Request is a genuine entity, then it would be better to use non-static members. But if it's not and methods are used in general, like Sinus function in math, then they'd be better to be static.
Overall it'd be better to declare static functions in a class that is just consisted of functions and no data members.
You should always create a class like if it was to be used on a non-static environment.
Then you can use that as a Singleton with lazy-instantiation. Or even as a Static class instantiation. Or even as a Standalone instance object. You decide later what to do with it.
If you start by declaring all members as static you are basically just covering a bunch of Global variables inside a glorified namespace known as a Class. You also will statically allocate the memory used by that class even if you don't call it or use it in your code.
So, just write as a Class, then you decide what to do with it. Static/Non-Static. Singleton/Instance. Factory Pattern or not. Memory Allocator X/DLL bound or whatnot.
The only exception is static members used for book-keeping in behalf of the Object Instances; things like reference counting, caches and things like that. That is the good thing about static/non-static, you can mix and match for some clever behaviors.
What if later you wanted another Request? Or what would happen if you can create more than one because you are in a multithreaded environment? Things will get really strange once you go that route with statics.
It looks like you are handling one particular request.
Now this insinuates you should make it a singleton, and/or use static functions.
Reason:
There is only one request, all the state is defined by the environment delivered to the process. The class methods are just helper functions, and you want to be able to use them without class instance.
On the other hand, you would rarely use static functions with classes that represent one of many, for example one user of many, one question of many.
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).
Example:
<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod(); // As of PHP 5.3.0
?>
See the reference of Static Keyword from php.net.
If you can, use static methods as a default. static methods run quicker than their non-static counterparts.