I have a class in which I want to define some constants used by other classes. The const keyword isn't enough for me because I want for example to use a mathematical expression like 2.0 * pi() as a constant. How is done?
I understand you want to assign a mathematical expression to a constant.
Like:
const FOO = 2.0*pi();
PHP constants can only contain scalar values. If you want other classes to use shared information, you will have to use static functions/methods for this.
Example:
static public function foo()
{
return 2.0*pi();
}
Actually something similar is implemented in PHP 5.6 where you can assign results of various expressions to class constants.
You can read more about it here:
http://php.net/manual/en/migration56.new-features.php#migration56.new-features.const-scalar-exprs
and here:
https://wiki.php.net/rfc/const_scalar_exprs
Assigning results of functions is still not allowed according to the documentation, however the following expression that has the same result as your example should be completely valid:
const FOO = M_PI*2;
Be advised that PHP 5.6 does not have a stable release yet, so it is not recommended for now to use it in production.
Related
I don't know if "declaration" is the right word for what I'm asking. It might be "definition" or something else.
PHP does not declare variables. You just define them by assigning a value.
But there are certain keywords that declare the existence of a new entity: const, function, class, and interface. They all have the same syntax:
keyword EntityName code
as in
const ConstantName = 1;
function FunctionName {...}
class ClassName {...}
interface InterfaceName {...}
I don't see anywhere in the PHP Manual where these keywords are discussed together but they definitely seem to play a kind of top-level role in the language. Each of them is documented in their own respective sections of the manual, but I wonder if there's a useful way to think about them in terms of the analogous roles they play. And are there other keywords in that category besides those four? Is there any combined documentation about them?
Despite PHP is a "weak type" language (so you can't declare variable types), PHP7 strenghtened the type protection (if strict_types is set to 1).
You can't declare a type in lines of code but you can asset them within functions declaration.
i.e.
function myfunction(float $a, float $b) : int {
return $a + $b;
}
Please note that we are declaring $a, $b types and the return type.
Another feature that allows you to "declare" variable types is the "new" operator (as many other OOP languages). With "new" you will instantiate your classes and this will never vary unless you perform a dynamic binding or casting.
Just to clarify the concepts you mention:
const : Declare a class constant (From PHP 5.3 you can use const outside classes also).
function: Classical PHP function/method declaration. PHP7 allows you to set parameter types and return types.
class : Class declaration.
interface: Interface declaration (special base class definition that can't have any implementation without inheritance).
Some useful resources for beginners.
(PHP7 OOP)
http://www.brainbell.com/tutorials/php/php7-oop-beginners.html
http://php.net/manual/en/reserved.keywords.php (from #Jacin comment)
(PHP7 types)
https://www.tutorialspoint.com/php7/php7_returntype_declarations.htm
http://blog.teamtreehouse.com/5-new-features-php-7
while studying oop in PHP, I noticed that the property declaration accepts an array as value as mentioned here PHP documentation
class Test{
public $var7 = array(true, false);
}
and I noticed that the documentation says :
This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
and after reading this article to know how the compilation process works, I realized that within the compilation process, some expressions would be evaluated and optimized if it possible like the below snippet :
var x = strlen ("testing") => int(7);
if using the array as a value in declaring property worked because it's evaluated in the compilation process, then why did not the below initialization work if logically both of them could be evaluated at the compilation process and this is the condition to initialize a property in a class?
Class Test {
public $vars=strlen("random"); // Fails
}
The short answer to your question is that strlen() is a function while array() is a keyword.
The critical difference to understand is that keywords always reference the same thing regardless of context.
From php.net:
These words have special meaning in PHP. Some of them represent things which look like functions, some look like constants, and so on - but they're not, really: they are language constructs. You cannot use any of the following words as constants, class names, function or method names.
Functions, on the other hand, could be defined differently depending on where you are calling them.
Consider this simplistic example:
First a file we'll call "functions.php".
//functions.php
namespace My_Project_Namespace;
function strlen($string){
return 10; //In my project, all strings are length 10! 10 is a nice round number...
}
In this file, I am overriding the built-in strlen() function with another one. This is possible because my function is defined inside a namespace (in this case, My_Project_Namespace).
Now consider your file, but this time let's put it in our namespace (you should be name-spacing all your functions and classes)
//Test.php
namespace My_Project_Namespace;
Class Test {
public $vars=strlen("random"); // Fails
}
strlen() has 2 definitions depending on the namespace. Since knowing the current namespace depends on runtime information the compiler cannot know which to use for initialization in the class. Even if you didn't define a custom strlen() function you still couldn't do this because knowing that there isn't another version strlen() also depends on runtime information!
array() is a totally different beast. It is a keyword, you cannot define another meaning for array() so the compiler doesn't have to worry about one existing.
How can I mark up constants using PHPDoc? What #-tag should I use? I've thought of #var, but that's not appropriate.
The short answer is that there isn't one. And there doesn't need to be one either. The documentation generator is smart enough to be able to see the constant declaration. So just put the summary there without any #-tags. That should be all that you need to do...
class foo {
/**
* This constant does something that you need.
*/
const FOO = 'bar';
}
For constants, you use #type.
In PHP, call_user_func(array(self, 'method_name')) doesn't work. The self keyword cannot be used in that context. I need to actually include the name of the class call_user_func(array('class_name', 'method_name')).
However, if I'm not in a static function, the $this variable does work in that context. Why the difference?
If you want the name of the current class context, use get_class() (without any parameters) or __CLASS__.
You've already written the difference; self is a keyword, and is not usable as a reference in an array (what kind of type should that be in PHP?). get_class() returns a string, and the array()-callback supports using a string as the first name to do a static call.
You can try with __CLASS__ to get the class name. Also it may work to use call_user_func('self::method_name') directly, but I didn't test it and the documentation about callbacks doesn't say anything about this.
self is just an undefined constant, so it expresses 'self'. So these two are the same:
array(self, 'method_name');
array('self', 'method_name');
And depending on the PHP version you use, this actually works, see Demo.
In case it does not work with your PHP version, some alternatives are:
call_user_func(array(__CLASS__, 'method_name'));
or
call_user_func(__CLASS__.'::method_name'));
or (in case you don't need call_user_func):
self::method_name();
Since PHP 5.5, you can do [self::class, 'methodName'].
::class is really useful for situations where you have a class name (maybe a local alias) and you need to generate the full class name as a string.
In PHP 5.3, you can write call_user_func('self::method') or call_user_func(array('self', 'method')). I suppose the latter could work in older versions as well.
In C#, variables and other things can be named protected names such as "class" by prepending the name with an # sign. So, #class is a valid name. Is it possible to do this same thing in PHP? I am using a class of constants to simulate an enum for HTML attributes such as ID, and Class. For now I am using "CssClass" but I'd rather use the name Class somehow.
Nope, not possible, at least not for class constants.
You cannot use any of the following [reserved] words as constants, class names, function or method names.
I don't know about C#, but there isn't any special symbol in PHP to transform a keyword into an identifier. As long as you don't name it exactly the same as a keyword (barring letter case), it'll just be any normal constant name.
How about a (different since it's not just CSS) prefix? Gets repetitive to type, but is a nice workaround. I realize this may be redundant as well if your class is named something like HTMLAttribute, but it's the easiest way out.
const A_ID = 'id';
const A_CLASS = 'class';
// etc
Yes, it is possible.
In fact you can define anything as constant:
define("define", 1);
define("class", 1);
define("if", 1);
define("=.+*", 1);
However, you can not use all defined constants.
You can query them with constant("if") again. But this is not exactly what you asked for. So unlike C# there is no shortcut to use any random constant. But as for naming them, there are almost no restrictions. (Might be a bug though. It's PHP.)
Constants:
The name of a constant follows the same rules as any label in PHP. A valid constant name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thusly: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
List of reserved keywords:
These words have special meaning in PHP. Some of them represent things which look like functions, some look like constants, and so on--but they're not, really: they are language constructs. You cannot use any of the following words as constants, class names, function or method name.
[see list here]
Within these rules you're free to make up your names. So, for instance, you could name a constant _CLASS, but not CLASS. I'd avoid the use of such ambiguous names though and namespace constants that are particular to the app, like MYAPP_CLASS.
Going from PHP5 to PHP7, a class constant could be named almost anything:
class ReservedWord
{
// Works in PHP >= 7.0 only
const NULL = null;
const TRUE = true;
}
However, thanks to this part of the manual and this comment, I've found that a class constant cannot be named these few things (see the test here):
class
static
__halt_compiler (oh, that was so useful!)
Edit: As I found in here in an RFC, the reason why class constant does not work is the name resolution ::class. However, still no idea about the two others.