What is the name of the :: operator? - php

I am new to PHP, and I am practicing with some online tutorials. I usually encounter the sign :: while going through books, online tutorial or blogs. Even if I check some PHP demo applications I see this operator. I tried to put this sign in Google, but I got unexpected results. I even tried to search it in other forums as well, but I didn't got the right answer. I usually call it a bubble colon, but what is its technical name?

:: is the scope resolution operator (you may sometimes find references to Paamayim Nekudotayim, hebrew for "double colon"). It is used to call static functions of a class, as in
class MyClass {
public static function hi() {
echo "hello, world";
}
}
MyClass::hi();
For more details on classes and objects, refer to the official documentation.

It has the exotic name "Paamayim Nekudotayim", but you may just call it Scope Resolution Operator.

It's called scope resolution operator. More information in Scope Resolution Operator (::) (PHP manual).

A single one is called a colon, so you could search for "php double colon" and would find this:
http://php.net/manual/en/keyword.paamayim-nekudotayim.php
Scope Resolution Operator (::)
Sometimes it is useful to refer to functions and variables in base classes or to refer to functions in classes that have not yet any instances. The :: operator is being used for this.

Related

PHP arrow / method call operator ("->") precedence

I'd like to have a reference stating clearly where PHP's arrow / method call operator (->) falls as regards the order of operator binding.
Unfortunately, the authoritative PHP manual page on operator precedence doesn't list it.
Example where someone could have doubts whether this could throw an exception because $price was first cast to string and only then the method call ->times() attempted:
return (string) $price->times($quantity);
In the answer, please indicate if there was any change here between PHP versions.
Bonus: does the static call (::) operator has the same precedence as ->?
$foo->bar(...) is classified in PHP's grammar as a member-call-expression.
This is a form of callable-variable, which itself is a form of variable. Essentially, a call to a member function on an object has the same precedence as any other "raw" variable - $foo->bar(...) and just $foo should be treated identically by the compiler. Neither is an "operator", and so they don't fit in the same hierarchy as the ones listed in the manual page you linked.
For your bonus question, :: is classed as a scoped-call-expression, which holds the same "precedence".

MyClass::class - get string representation of MyClass

The double colon (::) is the Scope Resolution Operator.
This is used to access protected methods and properties (and constants).
However, I have seen the use of ::class to return the string representation of the class. Like so:
namespace App;
class MyClass
{
}
var_dump(MyClass::class); # string(11) "App\MyClass"
I have searched far and wide for a documentation over this behaviour.
Is the above code also using the Scope Resolution Operator or is this something completely different? If so, what is the name of it?
If it is using the SRO, does that mean that PHP places a static property "class" behind the scenes? (I have been unable to override this static property though)
This is a new feature in PHP5.5, see: http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class
It's basically for getting the full class name. It's also not a static variable (see no preceding $) but a language feature using the class keyword. As per the note on php.net:
The class name resolution using ::class is a compile time transformation. That means at the time the class name string is created no autoloading has happened yet. As a consequence, class names are expanded even if the class does not exist. No error is issued in that case.
The operator ::class was introduced with PHP 5.5 and returns a string with the fully qualified class name.

What was the rationale for adding a second namespacing operator to PHP?

In PHP there are two namespacing operators:
\ and ::
:: is used for internal namespacing, e.g:
namespace example;
class Foo {
public static $bar = 'hello';
}
I can access $bar and other members of the Foo class via: Foo::$bar
The full namespaced name of Foo however is not example::Foo, it is example\Foo, and the full namespaced name of $bar would be example\Foo::$bar
What was the reason or rationale for using the two operators rather than sticking with one consistent operator that already existed?
You should take a peek at the namespace separator RFC, which calls out the actual arguments used in favor of and against the backslash.
The main reason why :: wasn't picked was due to the possible ambiguity it caused when doing scope resolution. Given that namespaces can be aliased (use \Foo\Bar as Baz;), all sorts of hilarious hijinks could be caused.
The :: is the Scope Resolution Operator and is only ment to access static classes. It has nothing to do with the namespace. Also the namespacing has been added in PHP 5.3, so long after static classes.
I guess thats why they use two different operators (for two different goals)

Why does empty expect T_PAAMAYIM_NEKUDOTAYIM when a non-variable is given?

<?php
define('foo', 'bar');
if (empty(foo)) {
echo 'qux';
}
http://codepad.org/G1TSK1c6
Parse error: syntax error, unexpected ')', expecting T_PAAMAYIM_NEKUDOTAYIM on line 4
I know that empty() only allows variables to be passed as an argument, but why does it expect a T_PAAMAYIM_NEKUDOTAYIM (i.e. ::) when I give it a constant?
The next logical thing the parser wants is a :: because foo is not a variable.
if (empty(foo::$bar)) {
}
Is the only thing, that works when empty() is not passed a variable. Your example is evaluated as empty(bar) where the parser assumes bar to be a class name and now expects a static member variable.
Saw this one while doing some research, although I know this is a bump I thought I would clarify this better.
empty() is not a function, but a language construct. This means that the underlaying parser code is different from that of parsing arguments sent to regular functions or methods. This may seem inconsistent at first when you experience serve error messages like that one, however lets break it down a little.
empty() is expecting to check something thats variable; a constant is not variable so that is not included in the list of possible syntaxes that can be passed to this construct, which makes perfect sense as you would otherwise be doing something illogical (checking for emptiness in a constant value).
The only other possible variables we have in PHP is good old variables and class properties as they are interchangeable, the relevant syntaxes can be represented like this:
<name> ::= [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
<variable> ::= $ <name>
<property> ::= <name> :: <name> || $ <name> :: <name> || $ <name> -\> <name>
This means that if you are passing a constant, PHP will read this as the class name and therefore is expecting the double colon token '::', hence why the error makes perfect sense.
Hope this was somewhat insightful ;-)
I looked into this, tried it on my local PHP installation and guess what? It worked without a hitch (PHP 5.5.6). After trying the same code on different versions of PHP, I found that it does not work on all versions of PHP < 5.5.x and works otherwise.
So then I took to PHP's documentation, more specifically its changelog from 5.4.x to 5.5.x, and found this:
http://www.php.net/manual/en/migration55.new-features.php#migration55.new-features.empty
empty() supports arbitrary expressions
Passing an arbitrary expression instead of a variable to empty() is now supported. For example:
if (empty(TRUE)) {
echo "This will NOT be printed.\n";
}
if (empty(FALSE)) {
echo "This will be printed.\n";
}
The above example will output:
This will be printed.
So if you're running PHP >= 5.5.x, then this will not be a problem.
You can test the code on different versions of PHP using this service: http://sandbox.onlinephpfunctions.com/. I could not, for the life of me, figure out how to save code samples (I always failed the captcha, even though it's dead simple - I think something MAY be broken on their end).
empty() expects variables and not constants. You should use defined() for constants.
Just a though, but I think this error is thrown when parsing the code.
foo, is not a variable, nor a string, therefore, in the context of parsing, the next solution may be class attribute., but it is not because there is no ::, but it should be because constants should not be used here, and it remains to be a class attribute or method.

PHP expects T_PAAMAYIM_NEKUDOTAYIM?

Does anyone have a T_PAAMAYIM_NEKUDOTAYIM?
It’s the double colon operator :: (see list of parser tokens).
It's Hebrew for "double colon".
It’s a name for the :: operator in PHP. It literally means "double colon". For some reason they named it in Hebrew. Check your code syntax, and put a :: where appropriate :-)
From Wikipedia:
In PHP, the scope resolution operator is also called Paamayim
Nekudotayim (Hebrew: פעמיים נקודתיים‎), which means “double colon” in
Hebrew.
The name "Paamayim Nekudotayim" was introduced in the
Israeli-developed Zend Engine 0.5 used in PHP 3. Although it has been
confusing to many developers who do not speak Hebrew, it is still
being used in PHP 5, as in this sample error message:
$ php -r :: Parse error: syntax error, unexpected
T_PAAMAYIM_NEKUDOTAYIM
As of PHP 5.4, error messages concerning the scope resolution operator
still include this name, but have clarified its meaning somewhat:
$ php -r :: Parse error: syntax error, unexpected '::'
(T_PAAMAYIM_NEKUDOTAYIM)
From the official PHP documentation:
The Scope Resolution Operator (also called Paamayim Nekudotayim) or in
simpler terms, the double colon, is a token that allows access to
static, constant, and overridden properties or methods of a class.
When referencing these items from outside the class definition, use
the name of the class.
As of PHP 5.3.0, it's possible to reference the class using a
variable. The variable's value can not be a keyword (e.g. self, parent
and static).
Paamayim Nekudotayim would, at first, seem like a strange choice for
naming a double-colon. However, while writing the Zend Engine 0.5
(which powers PHP 3), that's what the Zend team decided to call it. It
actually does mean double-colon - in Hebrew!
I know Hebrew pretty well, so to clarify the name "Paamayim Nekudotayim" for you, the paraphrased meaning is "double colon", but translated literally:
"Paamayim" means "two" or "twice"
"Nekudotayim" means "dots" (lit. "holes")
In the Hebrew language, a nekuda means a dot.
The plural is nekudot, i.e, dots, which function as vowels
The reason it why it's called Nekudo-tayim is because the suffix "-ayim" also means "two" or "twice", thus :: denotes "two times, two dots", or more commonly known as the Scope Resolution Operator.
This is also coming when you apply a constant in PHP to the empty() function:
if (!empty(SOME_CONSTANT)) {
}
That was my case. I solved it by using this:
$string = SOME_CONSTANT;
if (!empty($string)) {
}
Edit: Unfortunately, as of PHP 8.0, the answer is not "No, not anymore". This RFC was not accepted as I hoped, proposing to change T_PAAMAYIM_NEKUDOTAYIM to T_DOUBLE_COLON; but it was declined.
Note: I keep this answer for historical purposes. Actually, because of the creation of the RFC and the votes ratio at some point, I created this answer. Also, I keep this for hoping it to be accepted in the near future.
This can happen on foreachs when using:
foreach( $array as $key = $value )
instead of
foreach( $array as $key => $value )
For me this happened within a class function.
In PHP 5.3 and above $this::$defaults worked fine; when I swapped the code into a server that for whatever reason had a lower version number it threw this error.
The solution, in my case, was to use the keyword self instead of $this:
self::$defaults works just fine.
This just happened to me in a string assignment using double quotes. I was missing a closing curly on a POST variable...
"for {$_POST['txtName'] on $date";
should have been
"for {$_POST['txtName']} on $date";
I can't explain why. I mean, I see the error that would break the code but I don't see why it references a class error.
This just happened to me in a foreach loop. I had inadvertently typed ($array as $key as $value) and PHP objected to the first as.

Categories