Constants can't accept expressions that make calculations. Why can I declare DEFINE with random_int(1,4) and not get a fatal error? In this case, the value of the constant will be different every time the page loads. Is this correct for the ideology of constants?
define('RANDOM_NUMBER', random_int(2,4));
It's ideology question. Why is this correct in PHP? And why can use the expression in DEFINE but not in constants?
Constants can't accept expressions that make calculations.
This is not true.
define may accept as second parameter expressions, included values returned from a called function.
The restrictions for the value parameter of define are (from the manual)
value
The value of the constant. In PHP 5, value must be a scalar value (integer, float, string, boolean, or NULL). In PHP 7, array values are also accepted.
Of course a constant cannot be defined twice.
And -if I understand your question- this is the "ideology" of constants.
As they are defined the value cannot be modified in another part of the script as it's constant.
Of course if the script is run a second time the constant can get a different value like in your case.
Worth mentioning this is different for Class Constants - constants you declare inside a class definition with the keyword const.
Due to language design/specifications
The value must be a constant expression, not (for example) a variable, a property, or a function call.
Because the define function only get the result of random_int(2,4) as parameter and has no way to understand if it was created in a random or in a deterministic way.
What the program really does is:
$temp = random_int(2,4);
define("RANDOM_NUMBER", $x);
That said, the define is used to define a constant for a request script, not necessarily a constant for all requests, so it does make sense that every different request has a different value for the defined constant.
The official php documentation states:
While it is possible to define resource constants, it is not
recommended and may cause unpredictable behavior.
The same will apply to any non scalar values assigned to a DEFINE constant. The PHP documentation states that:
The value of the constant. In PHP 5, value must be a scalar value
(integer, float, string, boolean, or NULL). In PHP 7, array values are
also accepted.
Related
So I have recently learned about constants in PHP. fortunately there is not really anything to learn on them, they appear to be just an entity which stores value of something, just like a variable.
The only different that I can see (Correct me if I am wrong) is that a constant cannot be assigned a new value (that is it?). Which makes sense asthetically for example if you are making a config file with configurations that should not be changed.
But surely it brings other benefits/usage than just using a variable anyway?
In what situations should I be choosing to use constants?
If you find yourself setting a variable for convenience and never changing it during a script, the chances are you should be using a constant instead. Constants are like variables except that once they are defined they cannot be undefined or changed - they are constant as the name suggests. In many languages, constants are faster than variables and so are recommended, but this is not the case as much in PHP - although they are perhaps a small amount faster, the primary advantage to using constants is the fact that they do not have a dollar sign at the front, and so are visibly different from variables. Furthermore, constants are automatically global across your entire script, unlike variables.
To set a constant, use the define() function - it takes two parameters, with the first being the name of the constant to set, and the second being the value to which you wish to set it. For example, this following line of code sets the variable CURRENT_TIME to be the return value of the time() function, then prints it out:
define("CURRENT_TIME", time());
print CURRENT_TIME;
Note that it is not $CURRENT_TIME or Current_Time - constants, like variables, are case sensitive, but unlike variables they do not start with a dollar sign. You can change this behaviour by passing true as a third parameter to define(), which makes the constant case-insensitive:
define("CURRENT_TIME", time(), true);
print Current_TiMe;
There are two helpful functions available for working with constants, and these are defined() and constant(). The defined() function is basically the constant equivalent of isset(), as it returns true if the constant string you pass to it has been defined. For example:
define("CURRENT_TIME", time(), true);
if (defined("CURRENT_time")) {
/// etc }
Note that you should pass the constant name into defined() inside quotes.
A key characteristic of constants is that they behave like functions and classes, in the sense that they need to be defined when you try to use them, otherwise PHP will produce an error; and that they're global and unconcerned by scope. This makes them ideal for flags in function parameters, where the value is relatively unimportant, yet requires unique identification. Just look at how PHP itself uses constants:
json_encode($foo, JSON_UNESCAPED_UNICODE)
pathinfo($bar, PATHINFO_FILENAME)
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
What would the alternatives be?
$pdo->setAttribute('errmode', 'exception')
Strings cannot be checked for existence the same way constants can, typos are easier and require more manual error handling inside the function, and strings cannot be introspected the same way you can introspect PDO for its constants, and hence discoverability of available options is reduced.
$pdo->setAttribute(1, 2)
Magic numbers are obviously even worse, with even less meaning and the same lack of enforcement and discoverability.
In these cases, constants are ideal. They provide an enforced, readable identifier for a meaning; the actual value the constant holds is relatively unimportant.
Constants are for when someone else might read and try to install your code, but doesn't know what bits they should change to add their own details in. It's especially useful if you don't have an installation script, as the new admin will need to set their own details.
Example:
You need to install a new script on your website that uses a database of some kind. You'd open up the main file, and edit the constants that you need to add in your database connection details. Because they're constants, you know they shouldn't change - And they shouldn't, otherwise your database wouldn't work! If you use variables, the values could be accidentally changed in the script. It's also clearer to know which parts you have to change - and as they're usually at the start of a document or in a separate file easy to identify as well.
I know that if $var is NEVER declared, it can be declared WITH a sub-object like $var->mysubvar=1;
But if $var = “123” is mentioned ahead of time, then $var->mysubvar=1 will cause error. As it is declared ahead of time
I heard it was named "Dynamic Binding". But when I actually look into the term, I can not really find such description inside PHP Manual that match with this scenario and behavior.
Is this behavior call "Dynamic Binding"? Is there a specific name for it. But if it is the name then why PHP Manual did not include such technique or behavior?
The question is that What is the name to describe such behavior that one does not need to declare object ahead of time and an object will be automatically generated if there is sub-object is declared. (for example, javascript will not allow to manipulate an object without doing var myvar=1 (or equivalent), first.)
Answer:
Ah yea, its indeed deal with dynamic typing.
What is Dynamic Typing?
The issue you mentioned is related to dynamic typing, not necessarily dynamic binding. The PHP documentation on variable types covers this.
The type of a variable is not usually set by the programmer; rather, it is decided at runtime by PHP depending on the context in which that variable is used.
The reason your examples throw errors is because of a type mismatch.
For example, assuming $var isn't set, executing $var->mysubvar = 1 will create $var as an object. Attempting to follow it with $var = 5 will result in an error because your previous command specified that $var will be an object, not a scalar.
I've been searching for quite a while and cannot find what this method is actually called.
In PHP example:
$var->{'property_name'}
Depending on what you are accessing it will be called...
A variable variable
A variable property
A variable function
It is worth noting that the curly-braces are only needed when you need to disambiguate an expression (bear in mind the string you use may itself be stored in a variable!)
And so on. This is documented in the PHP manual for variable variables.
The following breaks my site quite badly:
define('FOO', get_foo());
However, the following works fine:
define('FOO', 'BAR');
You can't use function in define, this is not good. Define is used to make constants. Constants must not be changed, must have the same value during all the time. Functions, like get_foo(), can return different values. Php thinks that you want to put changable value to the constant. Try to put the result if this function to the variable:
$foo = get_foo();
Because define() expects a value for the constant and not the returned value of a function:
The value of the constant; only scalar and null values are allowed.
Scalar values are integer, float, string or boolean values. It is
possible to define resource constants, however it is not recommended
and may cause unpredictable behavior.
PHP is loosely Typed Language but could someone tell me, What is the default data type of any PHP variable? What is its implicit data Type?
PHP's variables are dynamic, and change depending on the data inside them. So they have no datatype by default.
From the manual on variables:
It is not necessary to initialize variables in PHP however it is a
very good practice. Uninitialized variables have a default value of
their type depending on the context in which they are used - booleans
default to FALSE, integers and floats default to zero, strings (e.g.
used in echo) are set as an empty string and arrays become to an empty
array.
So, they are what you make of them.
The OP understands that PHP is a loosely typed language and therefore the type of any initialized variable is determined by the data it holds; so read that way, the question then becomes What is the type of an uninitialized variable? - the answer to which is null
PHP doesn't generally allow you to declare variables without initializing them, there's no direct equivalent to:
Dim SomeVar
Therefore the only way to see that "default" data type is to evaluate either a variable that hasn't been set or a class member that holds no data.
1: A variable that hasn't been set
echo $someVar === null ? "NULL" : "NOT NULL"; //outputs NULL (and triggers a Warning)
2: A declared class member that holds no data
class Test {
public static $someVar;
}
var_dump(Test::$someVar); // outputs NULL
Therefore:
the type of any initialized variable is determined by the data it holds
the type of any uninitialized variable is null
Type Juggling
PHP does not require (or support) explicit type definition in variable declaration; a variable's type is determined by the context in which the variable is used. That is to say, if a string value is assigned to variable $var, $var becomes a string. If an integer value is then assigned to $var, it becomes an integer.
An example of PHP's automatic type conversion is the addition operator '+'. If either operand is a float, then both operands are evaluated as floats, and the result will be a float. Otherwise, the operands will be interpreted as integers, and the result will also be an integer. Note that this does not change the types of the operands themselves; the only change is in how the operands are evaluated and what the type of the expression itself is.
Source: http://www.php.net/manual/en/language.types.type-juggling.php