Function scope is out of class php - php

I want to know what is the scope that function who is out of class. Is it private, public or protected ?
function abc {
//code here
}
class xyz {
function car () {
// code here
}
}
Now what is the abc function scop ?
Please help me

Functions outside any class are global an can be called from anywhere. The same with variables.. just remember to use the global for the variables...
e.g
<?php
function abc() { }
$foo = 'bar';
class SomeClass {
public function tada(){
global $foo;
abc();
echo 'foo and '.$foo;
}
}
?>
functions are defined at a global level ; so, you don't need to do anything to use them from a method of your class.
For more informations, see the function page in the manual, which states (quoting) :
All functions and classes in PHP have the global scope - they can be called outside a function even if they were defined inside and vice versa.
If a "function" is defined inside a class, it's not called a "function" anymore, even if it is still the function that is used : it is called a "method"
Methods can be used statically :
MyClass::myMethod();
Or Dynamically :
$obj = new MyClass();
$obj->myMethod();
Depending on whether they were defined as static or not.

function abc {
//code here
}
This is a public function because function scope mainly in class and in your case abc
not inside a class so it behave as a public function
public scope to make that variable/function available from anywhere, other classes and
instances of the object.
private scope when you want your variable/function to be visible in its own class only.
protected scope when you want to make your variable/function visible in all classes that extend current class including the parent class.
reference What is the difference between public, private, and protected?

Related

different between static:: and $this-> and which syntax i should use?

I have some code:
class a {
public static function getCl() {
echo __CLASS__;
}
public function test() {
static::getCl();
}
}
class b extends a {
public static function getCl() {
echo __CLASS__;
}
}
$testClass = new b();
$testClass->test();
and this result : b. Then i try this:
class a {
public static function getCl() {
echo __CLASS__;
}
public function test() {
$this->getCl();
}
}
class b extends a {
public static function getCl() {
echo __CLASS__;
}
}
$testClass = new b();
$testClass->test();
this result is still b. I already know the different between static:: and self:: but can someone show me what is the different between static:: and $this-> in my code. Which one should i use?
Your context will produce the same result.
Here is simply description about both.
static:- refers late static binding As of PHP 5.3.0, PHP implements a feature called late static bindings which can be used to reference the called class in a context of static inheritance.
Static references to the current class like self:: or CLASS are resolved using the class in which the function belongs, as in where it was defined:
While Late static bindings tries to solve that limitation by introducing a keyword that references the class that was initially called at runtime. Basically, a keyword that would allow you to reference child class from parent class method. It was decided not to introduce a new keyword but rather use static that was already reserved.
$this:- refers current object.
Once inside an object's function, you have complete access to its variables, but to set them you need to be more specific than just using the variable name you want to work with. To properly specify you want to work with a local variable, you need to use the special $this variable, which PHP always sets to point to the object you are currently working with.

Why exactly does passing a closure from one class to another and calling it from the second class execute code from the first class?

It's pretty difficult to come up with a title for this question but basically here is the code:
<?php
class Sub {
protected $closure;
public function setClosure($closure) {
$this->closure = $closure;
}
public function callClosure() {
$this->closure->__invoke();
}
protected function outcome() {
echo 'calling from sub';
}
}
class Main {
public function __construct() {
$this->sub = new Sub();
}
public function start() {
$this->sub->setClosure(function() {
$this->outcome();
});
$this->sub->callClosure();
}
protected function outcome() {
echo 'calling from main';
}
}
$main = new Main();
$main->start();
The outcome of it is calling from main. This is exactly what I want, however, since I'll be dealing with this behavior and I don't fully understand why it works this way I would like some clarification.
Before writing the code I was expecting it to call the outcome method from the Sub class, not from the Main class. Does the closure use $this from the scope from which it was defined? What if, for whatever reason, I want it to use $this from the scope it's being called from?
It works properly and according to php anonymous functions manual because
The parent scope of a closure is the function in which the closure was
declared (not necessarily the function it was called from)
In php this anonymous functions implemented as Closure class.
And as already Mark Baker said when you create your closure inside your Main class you automatically get this bound object and this class scope.
The “bound object” determines the value $this will have in the
function body and the “class scope” represents a class which
determines which private and protected members the anonymous function
will be able to access. Namely, the members that will be visible are
the same as if the anonymous function were a method of the class given
as value of the newscope parameter.
In your case this class is Main not Sub

Access instance of class in callback anonymous function

I have a class with a few methods that take an anonymous function as a parameter. The class looks like this:
class MyClass {
public function myMethod($param, $func) {
echo $param;
user_call_func($func);
}
public function sayHello() {
echo "Hello from MyClass";
}
}
I'd like to be able to do things like this:
$obj = new MyClass;
$obj->myMethod("Hi", function($obj) {
echo "I'm in this anonymous function";
// let's use a method from myClass
$obj->sayHello();
});
So, in my anonymous function, since I passed $obj as a parameter to the anonymous function, I should be able to access its methods from within the anonymous function. In this case we'd see
I'm in this anonymous function
Hello from MyClass
How would I achieve this?
Thanks
Use the use construct:
$self = $this;
$obj->myMethod("Hi", function($obj) use($self) {
echo "I'm in this anonymous function";
// let's use a method from myClass
$obj->sayHello();
});
You've got to capture $this in another variable because use doesn't allow $this to be passed in, unless you are using PHP >= 5.4. Relevant quote from the documentation:
Closures may also inherit variables from the parent scope. Any such
variables must be passed to the use language construct. Inheriting
variables from the parent scope is not the same as using global
variables. Global variables exist in the global scope, which is the
same no matter what function is executing. The parent scope of a
closure is the function in which the closure was declared (not
necessarily the function it was called from).
Update
It may also be helpful to know that you retain the visibility of the class that you're currently in when the anonymous function is executing, as demonstrated in this simple script:
class Test
{
public function testMe()
{
$self = $this;
$tester = function() use($self) {
$self->iAmPrivate();
};
$tester();
}
private function iAmPrivate()
{
echo 'I can see my own private parts!';
}
}
$test = new Test;
$test->testMe();
Output:
I can see my own private parts!

PHP class constructors and methods

I just started learning PHP and I am having trouble with its syntax. I am learning how to write a class in php, and I used a syntax kinda similar to Java. However, I can get neither its constructor nor regular method to work and I can't figure out why.
<?php
class bento {
public $food;
public $staple = "rice";
protected $veggie = "kale";
public function __construct($fd){
$food = $fd;
}
public function getstaple(){
return $staple;
}
}
$chicken=new bento("chick");
echo "<br>".$chicken->food;
echo "<br>".$chicken->staple;
$fd=$chicken->getstaple();
echo "<br>".$fd;
echo "<br>".$chicken->getstaple();
?>
Here is the result that I have got:
//result
rice
//end of result
Basically, out of 4 lines, I only got one line to work (print out the $staple variable). The constructor did not assign "chick" value to $food. The getstaple() function did not return any value.
I can't figure out how to get this to work.
To refer to a class member, you should use $this->food or $this->staple
class bento {
public $food;
public $staple = "rice";
protected $veggie = "kale";
public function __construct($fd){
$this->food = $fd;
}
public function getstaple(){
return $this->staple;
}
}
The same in java, you need to access your class variables using the "this" keyword. In php, you would do something like:
$this->methodName();
or
$this->variableName
In PHP all variables are local to the scope they are defined within (with a few language provided exceptions like the superglobals $_GET, $_POST, $REQUEST, $_SERVER etc..)
This means that when you reference $food within your method your are referring to $food as it is defined within that method in other words a function variable as opposed to the instance property that you intended.
For instance methods PHP is nice enough to create for you a reference to the instance that a method was called on called $this This allows for you to reference properties and methods of an object from within the object itself via this format.
$this->food = $fd
Another thing to note is class methods and properties are not accessible this way. They require the use of the scope resolution operator :: so to get at a staticly defined class property or method you would use:
ClassName::method();
or
ClassName::$property;
As with $this php provides some easy access to the class properties via the self and static keywords.
self is a reference to the class that a static method was defined on.
static is a reference to the class that the static method was called on.
To illustrate the difference see this code
class A {
static public $toWho = "Class A";
static public function sayHelloSelf(){
echo "Hello ".self::$toWho;
}
static public function sayHelloStatic(){
eecho "Hello ".static::$toWho;
}
}
class B extends A {
static public $toWho = "Class B";
}
B::sayHelloSelf(); // echos Hello Class A
B::sayHelloStatic(); // echos Hello Class B
this keyword is used to access the class member within the current class.
You create class you have assign some value for variable $food.
then within the function you have tried to access the variable but $food is class variable we cannot access the class members without object or scope resolution operator.
"this" has current object name .

Strange behavior when overriding private methods

Consider the following piece of code:
class foo {
private function m() {
echo 'foo->m() ';
}
public function call() {
$this->m();
}
}
class bar extends foo {
private function m() {
echo 'bar->m() ';
}
public function callbar() {
$this->m();
}
}
$bar = new bar;
$bar->call();
$bar->callbar();
Now, changing the visibility of the m() method, I get:
(+ for public, - for private)
Visibility bar->call() bar->callbar()
======================================================
-foo->m(), -bar->m() foo->m() bar->m()
-foo->m(), +bar->m() foo->m() bar->m()
+foo->m(), -bar->m() ERROR ERROR
+foo->m(), +bar->m() bar->m() bar->m()
(protected seems to behave like public).
I was expecting everything to behave like it does when both are declared public. But although foo->call() and bar->callbar() are essentially the same thing, they yield different results depending on the visibility of m() in foo and bar. Why does this happen?
Inheriting/overriding private methods
In PHP, methods (including private ones) in the subclasses are either:
Copied; the scope of the original function is maintained.
Replaced ("overridden", if you want).
You can see this with this code:
<?php
class A {
//calling B::h, because static:: resolves to B::
function callH() { static::h(); }
private function h() { echo "in A::h"; }
}
class B extends A {
//not necessary; just to make explicit what's happening
function callH() { parent::callH(); }
}
$b = new B;
$b->callH();
Now if you override the private method, its new scope will not be A, it will be B, and the call will fail because A::callH() runs in scope A:
<?php
class A {
//calling B::h, because static:: resolves to B::
function callH() { static::h(); }
private function h() { echo "in A::h"; }
}
class B extends A {
private function h() { echo "in B::h"; }
}
$b = new B;
$b->callH(); //fatal error; call to private method B::h() from context 'A'
Calling methods
Here the rules are as follows:
Look in the method table of the actual class of the object (in your case, bar).
If this yields a private method:
If the scope where the method was defined is the same as the scope of the calling function and is the same as the class of the object, use it.
Otherwise, look in the parent classes for a private method with the same scope as the one of the calling function and with the same name.
If no method is found that satisfies one of the above requirements, fail.
If this yields a public/protected method:
If the scope of the method is marked as having changed, we may have overridden a private method with a public/protected method. So in that case, and if, additionally, there's a method with the same name that is private as is defined for the scope of the calling function, use that instead.
Otherwise, use the found method.
Conclusion
(Both private) For bar->call(), the scope of call is foo. Calling $this->m() elicits a lookup in the method table of bar for m, yielding a private bar::m(). However, the scope of bar::m() is different from the calling scope, which foo. The method foo:m() is found when traversing up the hierarchy and is used instead.
(Private in foo, public in bar) The scope of call is still foo. The lookup yields a public bar::m(). However, its scope is marked as having changed, so a lookup is made in the function table of the calling scope foo for method m(). This yields a private method foo:m() with the same scope as the calling scope, so it's used instead.
Nothing to see here, error because visibility was lowered.
(Both public) The scope of call is still foo. The lookup yields a public bar::m(). Its scope isn't marked as having changed (they're both public), so bar::m() is used.
A private method is not overridable, as a private method is not visible even to its subclasses. Defining a method as protected means it is not visible outside of the class itself or its subclasses.
If you have a method that you want to use from your parent class but want children to able to modify its behaviour, and don't want this method available externally, use protected. If you want functionality in your parent class that cannot be modified in any way by subclasses, define the method as private.
EDIT: to clarify further, if you have two methods with the same name in a parent and subclass, and these methods are defined as private, essentially the subclass method has absolutely no relation to the parent method. As stated, a private method is COMPLETELY INVISIBLE to the subclass.
Consider this:
class foo {
private function m() {
echo 'foo->m() ';
}
private function z() { echo "foo->z();"; }
public function call() {
$this->m();
}
}
class bar extends foo {
private function m() {
echo 'bar->m() ';
}
public function callbar() {
$this->m();
}
public function callz()
{
$this->z();
}
}
Calling $bar->callz(); is going to produce an ERROR, because z does not exist in the subclass at all, not even as an inherited method.
According to the PHP manual:
Members declared as private may only
be accessed by the class that defines
the member.
http://www.php.net/manual/en/language.oop5.visibility.php
EDIT
they yield different results depending
on the visibility of m() in foo and
bar. Why does this happen?
If m() in foo is public, it is overridable. When this is the case m() from bar overrides m() in foo.

Categories