I was marvelled when I tested the following code today:
$star = "Aquarius";
$star = 11;
While debugging, I observed that $star simply changes from string type to integer type. I was amazed by this functionality. In C++ for instance, this is just impossible, but in c# I considered the var variable but it's not the same.
For instance you can't do:
var dynamic = "Hello";
dynamic = 3;
I began to wonder what exactly happens at the point when I basically say $star = 11. My guess is that $star is simply reinitialized since it's being directly assigned to (but this seems weird since the interpreter already knows that a variable $star has been declared earlier). Can anyone help with some clear or official source-backed explanation?
Thanks.
In C/C++ the type is defined at compile time because of the kinds of optimization that can occur based on it.
In C# the compiler infers the type based on the context and in the compilers brain it substitutes the var keyword for the type. This is why you can not change the type after the compiler made the initial inference.
In scripting languages like PHP a variable is an entry into a Hash Map (Associative Array, a Symbol Table). This defines the namespace (and scope). The actual value part is a generic object type that stores both the value and the type.
PHP is a dynamic language, similar in spirit to Perl, Ruby, Python, or many others. C++, on the other hand, is compiled and statically typed, requiring each variable to have a type defined at compile time.
Check the PHP docs for some great insight to PHP's dynamic typing implementation:
http://php.net/manual/en/language.types.type-juggling.php
PHP is a loosely typed language. PHP converts the variable to the correct data type, according to the value.
Check this out - http://php.net/manual/en/language.types.type-juggling.php
Related
If I understand correctly what type hinting in php in fact does, it checks type and throws an error if it is not as declared.
That seems to me more than just a "hint" – more like a (full) "check" (like java - my main programming background).
So, I'm wondering if I'm missing something or what the intent was in naming it that way.
PHP does not check variable types and types are not declared within variable declaration. PHP always tries to convert variable to correct type when required. If you str_replace on number, number will be temporarily converted to string.
As you can see there http://php.net/manual/en/language.types.type-juggling.php
So its exactly the opposite from java.
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 have been doing some research online and it appears that the answer to my question is no, but I realize there are times when I might miss something or search for something incorrectly. I know in languages like C++, when a variable is declared it can be declared as int or string. Is it possible to force this in PHP?
For Example:
<?php
(int)$var = 5;
?>
will be validated and not cause an error in PHP, but:
<?php
$var = 5;
?>
will cause an error because it was not cast as a type string, int, object, etc...
I know PHP is loosely typed so this may not be an option, however I would like to use it that way I ensure that I sanitize data appropriately and improve readability by letting others know exactly what is going on with the code. I am hoping there is a way to enforce this in the php.ini file or to load it in a script that will always be executed by my program.
Thank you for any help you can offer!
PHP is loosely typed and does not require you to declare a variable type when declaring a variable. You can’t change that behavior with a magic php.ini directive.
The benefit of having “loose typing” is that it allows for flexibility. It allows you to create dynamic applications without having to worry about the type of the variable – PHP makes this possible by not enforcing variable types.
However, if you must convert a variable into a particular format, just cast it:
$int = (int) $foo;
$str = (string) $foo;
$bool = (bool) $foo;
$float = (float) $foo;
...
There are functions to do the same, e.g. intval(), strval(), boolval() – all of them do the same task, but a function is very useful when you want to use it as a callback to another function.
I haven't done much programing in many languages, but I know in C(++), you have to declare a variable type (int,char,etc).
In PHP you, of course, don't have to do that. You can start with $str = "something"; then later $str = array("something" => "smells"); and she is happy.
How does PHP compile? How does it know what the variable type is going to be? Does it even care?
This question has no relevance to anything I am doing. I am just curious.
EDIT.
I need to clarify this question a little bit.
In C, if I say:
int y;
It reserves x amount of bytes for y. If y overflows, bad news.
PHP doesn't have this nature (at least I don't think it does).
$i = "a number";
$i = 8;
$i = 1000000000000000000;
It's all the same to the language. How does it know how much to reserve? Or am I comparing Apples to Oranges? If I am going about this wrong, do you have any good topics that I can read to better understand?
Since you have C experience, consider a PHP variable to be like the following:
typedef struct {
int varType;
void* data;
} variable_t;
when you create a new variable, it will create a variable_t, give it a type tag (lets say 1 for int, 2 for string), and store it in a list somewhere (by scope, reference by name). The actual contents will be stored in *data. When the variable is again accessed, the type can be determined from int varType, and the appropiate action taken on void* data, such as using it as an int or string.
Imagine that the PHP snippet:
$data = 12;
$data2 = $data + 1;
$data = "Hello";
produces instructions like the following (pseudo-Cish):
Line 1:
variable_t* var = new_variable(TYPE_INT, data);
store_variable("data", var);
Line 2:
variable_t* var = get_variable("data2");
if (var->varType == TYPE_INT)
int value = 1 + *(int*)var->data);
else
error("Can't add non int");
var = new_variable(TYPE_INT, value);
store_variable("data2", var);
Line 3:
variable_t* var = get_variable("data");
if (var)
destroy_variable(var);
// Do like line 1, but for TYPE_STRING
This type of augmented data works in bytecoded, compiled, or direct interpreted languages.
There are more details in regards to different virtual machine implementations (local allocation, heap allocation, register VMs, etc). If you actually want to understand how virtual machines work, the best reference is Lua. Very clean language, very clean bytecode, and very clean virtual machine. PHP is probably the last implementation you should look at.
PHP doesn't really compile -- it is interpretted (into op-codes).
Pretty much if you try to do something on a certain data type that can't be done, it'll give you an error. There is no type checking.
It doesn't compile. It is an interpreted language, like Javascript.
I realize this is an old question but here is some more specific information on how PHP handles the questions asked by the OP.
This is the page from the PHP reference that you'd want to start with:
Introduction to Variables
I know linking isn't preferred but that link should be stable and I don't want to wholesale copy PHP reference documentation. Here are the highlights.
OP: How does PHP know what type of variables it uses (or does it)?
PHP is written in C and uses a C struct typedef which it calls a zval along with a C union typedef which is calls a zval_value to represent all variables.
typedef struct _zval_struct {
zvalue_value value; /* variable value */
zend_uint refcount__gc; /* reference counter */
zend_uchar type; /* value type */
zend_uchar is_ref__gc; /* reference flag */
} zval;
"The engine attempts to cover up the complexity of the concept of a variable that can be any type by providing a uniform and intuitive set of macros for accessing the structures various fields."
"PHP is a dynamic, loosely typed language, that uses copy-on-write and reference counting." Reference Counting and Copy-on-write (COW) are two powerful concepts PHP uses which I won't go into here but are worth reading about.
"Weak typing is implicit of the engine's preference to convert, or coerce variables into the required type at execution time. Reference counting is the means by which the engine can deduce when a variable no longer has any references in the users code, and so is able to free the structures associated with the variable."
"The zval_value is a union which can represent all types a variable may hold."
" ... a variable can be of one type, the variable data is represented by the appropriate field in the zval_value union. The zval itself holds the type, reference count and a flag to indicate if a variable is a reference."
How does PHP compile?
"Compile" is a broad word that can have different meanings and PHP doesn't compile in the traditional sense. It does do a sort of pre-compilation which converts the source code into opcodes which are instructions that can be executed by the processor. These opcodes are cached which prevents PHP from have to parse frequently called scripts.
How does it know what the variable type is going to be? Does it even care?
As already quoted above it is the PHP engine's "preference to convert, or coerce variables into the required type at execution time." Baiscally PHP does always store what it determines a variable's type to be when it's created but when a variable is referenced PHP makes another determination of what the type is based on the context in which it is being used.
"PHP is weakly typed, as such the engine provides API functions for converting variables from one type to another."
The engine has a set of macros it uses for working with the zvals to convert a variable's type so that you usually don't have to deal with that.
If you want to see what zvals look like in action they can be dumped with:
debug_zval_dump($variableName);
"How does PHP compile? How does it know what the variable type is going to be? Does it even care?
This question has no relevance to anything I am doing. I am just curious."
PHP is an interpreted language and it doesn't compile.
PHP doesn't know what type the variable is going to be, because the type of the variable is determined by the type of the value which was assigned last time to that variable.
You can do this:
$foo = 5;
var_dump($foo);
$foo = "5";
var_dump($foo);
$foo = array();
$foo[] = 0;
$foo[] = 1;
$foo[] = 2;
var_dump($foo);
As you can see, whenever a value is assigned to foo, the type might be changed.
PHP doesn't care about the type of your variable, because it's a programming language and it doesn't have feelings.
EDIT:
"Or am I comparing Apples to Oranges?"
Yes, you are. Here you can learn more about the language.
EDIT2:
PHP is a scripting language with an interpreter and without a compiler. This means that in PHP you can only get runtime errors. It's a liberal language if we consider types, because you have the right to do anything with your variables and their types will be modified according to the usage of them.
These links might be useful for you:
http://www.gidforums.com/t-11866.html
http://www.webmaster-talk.com/coding-forum/186350-fundamental-differences-between-php-c-c.html
Variable scope difference between PHP and C: block scope is not exactly the same?
Note, that PHP is executed on the server, if you want to create client events, Javascript is my suggestion.
PHP now supports type hinting, you can include things like 'string' or 'array' in function definitions that are caught as the scripts are parsed to indicate there is a type mismatch.
Why is it not possible to do something equivalent to this in PHP:
(Array(0))[0];
This is just for sake of argument, but it seems strange it does not allow access of anonymous objects. I would have to do something like the following:
$array = Array(0);
$array[0];
Any ideas why this is the behavior of PHP?
I read something somewhat detailed about this once and I regret not bookmarking it because it was quite insightful. However, it's something along the lines of
"Because the array does not exist in memory until the current statement (line) executes in full (a semicolon is reached)"
So, basically, you're only defining the array - it's not actually created and readable/accessible until the next line.
I hope this somewhat accurately sums up what I only vaguely remember reading many months ago.
This language feature hasn’t been inplemented yet but will come in PHP 6.
I guess the short answer is: nobody has coded it yet. I've used (and loved) that syntax in both Python and Javascript, but still we wait for PHP.
The main reason is because unlike some languages like Python and JavaScript, Array() (or in fact array()) is not an object, but an language construct which creates an inbuilt data type.
Inbuilt datatypes themselves aren't objects either, and the array() construct doesn't return a reference to the "object" but the actual value itself when can then be assigned to a variable.