obj = &new classname()
and
obj = new className()
what is difference b/w use to create reference object and object?
What is advantage use of reference object when we create object
Assigning the return value of the new construct as reference is deprecated since PHP 5 (I think). This was valid (maybe necessary?) in PHP 4, but generates a STRICT warning in PHP 5.
error_reporting(E_ALL)
at the beginning of a test script should yield the message that the first variant is old coding style. See the handbook for more information (e.g. user comments)
Related
This question already has answers here:
Why can't I access DateTime->date in PHP's DateTime class?
(5 answers)
Closed 5 years ago.
Consider the following code sample:
$m_oDate = new DateTime('2013-06-12 15:54:25');
print_r($m_oDate);
echo $m_oDate->date;
Since PHP 5.3, this produces (something like) the following output:
DateTime Object
(
[date] => 2013-06-12 15:54:25
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
2013-06-12 15:54:25
However the following code:
$m_oDate = new DateTime('2013-06-12 15:54:25');
echo $m_oDate->date;
...simply emits an error:
Notice: Undefined property: DateTime::$date in ...
Why does print_r() "add" these properties to the object? Note that they are not defined as part of the DateTime class on the manual page.
This has been reported as Bug #49382 in PHP.
In PHP 5.3, internal functionality was added to allow print_r() to show details of the underlying timestamp value held by an instance of DateTime, to assist with debugging. A side effect of this change is that when the object is dumped to text, these phantom public properties are added to the instance.
The same effect can be achieved by using reflection to access these properties, and if you need to access the properties then using reflection would be the way to go, so you don't provoke the error.
However, it should be noted that you shouldn't really use these properties - since they are not defined as members of the object, there is no guarantee they will continue to carry the same data (or even exist) in future PHP versions. If you need to access the information, use the following methods, defined as part of the API, instead:
// $obj->date
$obj->format('Y-m-d H:i:s');
// $obj->timezone
$obj->getTimezone()->getName();
// or...
$obj->getTimezone()->getOffset();
// or...
$obj->getTimezone()->listAbbreviations(); // returns an array, so may need
// further processing to be of use
NB: The timezone_type property is not accessible through the PHP API. It is an internal value and not useful in userland, because it describes the type of string that timezone holds when the object is dumped - i.e. one of the three methods for obtaining timezone information in the code sample above. For completeness, its possible values are defined in the following way:
Value | Type | Userland equivalent
------+-----------------------+----------------------------------
1 | time offset | DateTimeZone::getOffset()
2 | TimeZone abbreviation | DateTimeZone::listAbbreviations()
3 | TimeZone identifier | DateTimeZone::getName()
There is some magic occurring but it's pretty simple.
The class DateTime doesn't have a public variable 'date' that you're meant to access. However, as a side effect of how PHP works, there is a variable created when you call print_r or var_dump on that class.
After that magic happens 'date' is available, but it shouldn't be. You should just use the getTimestamp function to make your code work reliably.
There's no date property in DateTime; that's why you're getting (Undefined property: DateTime::$date).
print_r() performs some introspection on the object to display its contents; this causes the object to magically create the ::date property. This is not documented though, so using this may break your code in the future.
You need something like $m_oDate->format('m-d-Y'); instead.
The problem lies here:
static HashTable *date_object_get_properties(zval *object TSRMLS_DC)
{
// ...
zend_hash_update(props, "date", 5, &zv, sizeof(zval), NULL);
// ...
The function date_object_get_properties is called when any data dumping is made (print_r, var_dump, var_export). The hash table is updated for data representing, unfortunately this is made public.
Consider the following code-example:
$m_oDate = new DateTime('2013-06-12 15:54:25');
some_func($m_oDate);
echo $m_oDate->{'ROXXOR_IS_BACK!!'};
The most obvious difference to yours is that instead of the print_r function a different one some_func is called. The expectations might differ because you know print_r but you don't know some_func but that is only to sharpen your senses. Let's wait a moment until I show the definition of that function.
The second difference is the name of the property that is getting echoed. Here I've choosen a name that is really exceptional: {'ROXXOR_IS_BACK!!'}, again to sharpen your senses.
This name is that crazy that is must be obvious not being part of DateTime albeit when the example above is executed, it's totally clear that this roxxor property must exists. Program Output:
PHP never lets you down.
So how come? Yes, you sure already have an idea how that works. The some_func() function must have added it. So let's take a look into the functions definition:
function some_func($m_oDate) {
$m_oDate->{'ROXXOR_IS_BACK!!'} = 'PHP never lets you down.';
}
Yes, it's now clearly visible that this function has added a property to the object. And it also shows that this is totally easily possible with any object in PHP.
Compare with an array in PHP, you can also add new keys when you want to.
This example has not been chosen out of nothing, because this is where objects in PHP come from: They are just syntactic sugar around arrays and this has to with the time when objects in PHP were introduced back in PHP 3:
At the time classes were introduced to the source tree of what was to become PHP 3.0, they were added as syntactic sugar for accessing collections. PHP already had the notion of associative array collections, and the new critters were nothing but a neat new way of accessing them. However, as time has shown, this new syntax proved to have a much more far-reaching effect on PHP than was originally intended.
-- Zeev Suraski about the standard object since PHP 3 (archived copy) - via Why return object instead of array?
This is also the simple explanation why it's totally common in PHP that functions can add member variables which have not been defined earlier in the class. Those are always public.
So when you do assumptions about some object having a property or not, take a look where it comes from. It must not be part of the class but might have been added later.
And keep the following in mind:
Do not use print_r and var_dump in production code.
For the fun of it, this is how you can make it work, using Reflection:
$m_oDate = new DateTime('NOW');
$o = new ReflectionObject($m_oDate);
$p = $o->getProperty('date');
echo $p->getValue($m_oDate);
Source
You should use DateTime::format or DateTimeImmutable::format as the case may be instead
$m_oDate = new DateTime('NOW');
echo $m_oDate->format("r");
This question already has answers here:
Why can't I access DateTime->date in PHP's DateTime class?
(5 answers)
Closed 5 years ago.
Consider the following code sample:
$m_oDate = new DateTime('2013-06-12 15:54:25');
print_r($m_oDate);
echo $m_oDate->date;
Since PHP 5.3, this produces (something like) the following output:
DateTime Object
(
[date] => 2013-06-12 15:54:25
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
2013-06-12 15:54:25
However the following code:
$m_oDate = new DateTime('2013-06-12 15:54:25');
echo $m_oDate->date;
...simply emits an error:
Notice: Undefined property: DateTime::$date in ...
Why does print_r() "add" these properties to the object? Note that they are not defined as part of the DateTime class on the manual page.
This has been reported as Bug #49382 in PHP.
In PHP 5.3, internal functionality was added to allow print_r() to show details of the underlying timestamp value held by an instance of DateTime, to assist with debugging. A side effect of this change is that when the object is dumped to text, these phantom public properties are added to the instance.
The same effect can be achieved by using reflection to access these properties, and if you need to access the properties then using reflection would be the way to go, so you don't provoke the error.
However, it should be noted that you shouldn't really use these properties - since they are not defined as members of the object, there is no guarantee they will continue to carry the same data (or even exist) in future PHP versions. If you need to access the information, use the following methods, defined as part of the API, instead:
// $obj->date
$obj->format('Y-m-d H:i:s');
// $obj->timezone
$obj->getTimezone()->getName();
// or...
$obj->getTimezone()->getOffset();
// or...
$obj->getTimezone()->listAbbreviations(); // returns an array, so may need
// further processing to be of use
NB: The timezone_type property is not accessible through the PHP API. It is an internal value and not useful in userland, because it describes the type of string that timezone holds when the object is dumped - i.e. one of the three methods for obtaining timezone information in the code sample above. For completeness, its possible values are defined in the following way:
Value | Type | Userland equivalent
------+-----------------------+----------------------------------
1 | time offset | DateTimeZone::getOffset()
2 | TimeZone abbreviation | DateTimeZone::listAbbreviations()
3 | TimeZone identifier | DateTimeZone::getName()
There is some magic occurring but it's pretty simple.
The class DateTime doesn't have a public variable 'date' that you're meant to access. However, as a side effect of how PHP works, there is a variable created when you call print_r or var_dump on that class.
After that magic happens 'date' is available, but it shouldn't be. You should just use the getTimestamp function to make your code work reliably.
There's no date property in DateTime; that's why you're getting (Undefined property: DateTime::$date).
print_r() performs some introspection on the object to display its contents; this causes the object to magically create the ::date property. This is not documented though, so using this may break your code in the future.
You need something like $m_oDate->format('m-d-Y'); instead.
The problem lies here:
static HashTable *date_object_get_properties(zval *object TSRMLS_DC)
{
// ...
zend_hash_update(props, "date", 5, &zv, sizeof(zval), NULL);
// ...
The function date_object_get_properties is called when any data dumping is made (print_r, var_dump, var_export). The hash table is updated for data representing, unfortunately this is made public.
Consider the following code-example:
$m_oDate = new DateTime('2013-06-12 15:54:25');
some_func($m_oDate);
echo $m_oDate->{'ROXXOR_IS_BACK!!'};
The most obvious difference to yours is that instead of the print_r function a different one some_func is called. The expectations might differ because you know print_r but you don't know some_func but that is only to sharpen your senses. Let's wait a moment until I show the definition of that function.
The second difference is the name of the property that is getting echoed. Here I've choosen a name that is really exceptional: {'ROXXOR_IS_BACK!!'}, again to sharpen your senses.
This name is that crazy that is must be obvious not being part of DateTime albeit when the example above is executed, it's totally clear that this roxxor property must exists. Program Output:
PHP never lets you down.
So how come? Yes, you sure already have an idea how that works. The some_func() function must have added it. So let's take a look into the functions definition:
function some_func($m_oDate) {
$m_oDate->{'ROXXOR_IS_BACK!!'} = 'PHP never lets you down.';
}
Yes, it's now clearly visible that this function has added a property to the object. And it also shows that this is totally easily possible with any object in PHP.
Compare with an array in PHP, you can also add new keys when you want to.
This example has not been chosen out of nothing, because this is where objects in PHP come from: They are just syntactic sugar around arrays and this has to with the time when objects in PHP were introduced back in PHP 3:
At the time classes were introduced to the source tree of what was to become PHP 3.0, they were added as syntactic sugar for accessing collections. PHP already had the notion of associative array collections, and the new critters were nothing but a neat new way of accessing them. However, as time has shown, this new syntax proved to have a much more far-reaching effect on PHP than was originally intended.
-- Zeev Suraski about the standard object since PHP 3 (archived copy) - via Why return object instead of array?
This is also the simple explanation why it's totally common in PHP that functions can add member variables which have not been defined earlier in the class. Those are always public.
So when you do assumptions about some object having a property or not, take a look where it comes from. It must not be part of the class but might have been added later.
And keep the following in mind:
Do not use print_r and var_dump in production code.
For the fun of it, this is how you can make it work, using Reflection:
$m_oDate = new DateTime('NOW');
$o = new ReflectionObject($m_oDate);
$p = $o->getProperty('date');
echo $p->getValue($m_oDate);
Source
You should use DateTime::format or DateTimeImmutable::format as the case may be instead
$m_oDate = new DateTime('NOW');
echo $m_oDate->format("r");
For example, I have the following class.
class A {
public $foo = 1;
}
$a = new A;
$b = $a; // a copy of the same identifier (NB)
According to the current PHP docs a copy of the identifier is made, has this always been the case? If not, when did it change?
This wasn't always the case. In PHP4 an object was copied when assigned to a new variable. When PHP5 was introduced this changed to pass a reference of the object being assigned.
(From the manual)
In PHP 5 there is a new Object Model. PHP's handling of objects has been completely rewritten, allowing for better performance and more features. In previous versions of PHP, objects were handled like primitive types (for instance integers and strings). The drawback of this method was that semantically the whole object was copied when a variable was assigned, or passed as a parameter to a method. In the new approach, objects are referenced by handle, and not by value (one can think of a handle as an object's identifier).
Why would you do this?
$a = &new <someclass>();
For example, the documentation for SimpleTest's SimpleBrowser uses this syntax (http://www.simpletest.org/en/browser_documentation.html).
$browser = &new SimpleBrowser();
Is there any use to this? Is this a relic of PHP 4?
Edit:
I understand that the ampersand returns by reference, but what is the point of returning a NEW instance of an object by reference?
In PHP5, objects are passed using opaque object handles. You can still make a reference to a variable holding such a handle and give it another value; this is what the &new construct does in PHP5. It doesn't seem to be particularly useful though – unless you clone it explicitly, there's only ever one copy of a particular object instance, and you can make references to handles to it anytime after instantiation if you want to. So my guess would be the code you found is a holdover from when &new was a necessary pattern.
Since PHP5 new returns references automatically. Using =& is thus meaningless in this context (and if I'm not mistaken giving a E_STRICT message).
Pre-PHP5 the use of =& was to get a reference to the object. If you initialized the object into a variable and then assigned that to a new variable both of the variables operated on the same object, exactly like it is today in PHP5.
I am getting a deprecated warning because of a library I am using. The statement is the following :
$this->_ole =& new OLERead();
The thing is I don't see why one would want to use & new in an instantiation.
If I am not mistaken, the & operator tells PHP to copy the reference to the instance, and not the instance itself. But in that case, isn't it pointless to ask for a copy of a reference that isn't stored ?
But since I don't exactly know how new exactly works, maybe this was supposed to save some obscure garbage collection, or something like that.
What do you think about that ?
From the documentation:
As of PHP 5, the new operator returns a reference automatically, so assigning the result of new by reference results in an E_DEPRECATED message in PHP 5.3 and later, and an E_STRICT message in earlier versions.
The library you use was probably developed for PHP 4.
Helpful information about why this was used can also be found in the migration guide:
In PHP 5 there is a new Object Model. PHP's handling of objects has been completely rewritten, allowing for better performance and more features. In previous versions of PHP, objects were handled like primitive types (for instance integers and strings). The drawback of this method was that semantically the whole object was copied when a variable was assigned, or passed as a parameter to a method. In the new approach, objects are referenced by handle, and not by value (one can think of a handle as an object's identifier).
That's an idiom for PHP4 compatibility. Objects were passed as copies per default there, and this is a workaround to always have references to an instance.
In PHP4, new returned a value and not a reference.
This is not the case in PHP5.
If you write $this->_old =& new OLERead(); a changement of _ole in any object will updates all references to the new object.
This is not the case without & .
EDIT: And yes, in previous versions of PHP, object were passed by copy. At the end, this is quite hard to have a consistent behaviour accross versions.