typecasting to an object

what is the difference between


$test_object = (object) array(
  'hello' => 'world',
  'nested' => array('key'=>'value'),
);


and
$test_object = (object) 12345;



I modified code to show both
echo '<h2>Testing typecasting to an object</h2>';
$test_object = (object) array(
  'hello' => 'world',
  'nested' => array('key'=>'value'),
);
echo '<tt><pre>'.var_export($test_object,TRUE).'</pre></tt>';

echo '<h2>Testing typecasting to an object scaler</h2>';
$test_object = (object) 12345;
echo '<tt><pre>'.var_export($test_object,TRUE).'</pre></tt>';

Open in new window





output

Testing typecasting to an object
stdClass::__set_state(array(
   'hello' => 'world',
   'nested' =>
  array (
    'key' => 'value',
  ),
))
Testing typecasting to an object scaler
stdClass::__set_state(array(
   'scalar' => 12345,
))




3 minute lynda.com tutorial transcript
00:00	In this chapter, I'm going to explore built-in PHP objects.
00:04	I'll start with the standard class, which is pretty generic,
00:07	then demonstrate how to get objects from the database.
00:10	We'll handle errors in an object-oriented way, then customize them to meet our needs.
00:14	Let's start with the standard class.
00:16	A standard class is a generic class that can be created by typecasting a value
00:20	as an object, like casting the string "hello, world" as an object.
00:24	It won't have any methods, but it will have values.
00:27	In case you were wondering, if you typecast an object to an object, that's kind of
00:31	goofy, and nothing will happen.
00:34	If you typecast that array to an object, the result will be an object with
00:37	properties named for the keys to the array, with values corresponding to the array values.
00:43	Let's clean up the demo, and remove the cloning tests.
00:46	Create a test standard class object out of a nested array.
00:51	Echo <h2> Testing typecasting to an object>.
01:01	$test_object = (object). This is the typecasting. array. hello as the key and
01:10	world as the value. Then nested as an array ( 'key => value').
01:24	Then, debug the test object.
01:29	Save, then refresh your browser.
01:33	The result will be a standard class with properties "hello" and "nested," with nested
01:37	containing an array.
01:39	If I was to typecast any other data type like a string, the value would be
01:43	converted to a standard object, with one property named scalar.
01:47	Return to the demo, and replace the array definition with the number 12345. Save, and refresh.
02:00	The test object now has one property, scalar, with the value 12345.
02:07	Standard class objects are practically used in a number of ways.
02:10	For example, returning a defined data structure with fixed branches without nesting.
02:16	Sometimes, it's used as a shorthand to speed code development, as it takes less
02:20	characters to access a property than it does to specify a key.
02:24	Finally, you can use a standard object when interacting with a method that is
02:28	looking for an object with particular properties, but isn't actually
02:31	checking for the class.
02:33	In the next video, I will show you how to load objects directly from the
02:37	database, then intelligently load addresses from the database into the
02:40	correct class.

Open in new window

LVL 1
rgb192Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
What do you actually need to know?

Casting to an object does exactly that - takes one type and makes it work like an object. In the case of the array the elements become properties that can be accessed (using your example) like so

$test_object->hello
But the nested array would still be an array
$test->object->nested['key'];

In the second example the casting to an object of a scaler results in an object being created with a single property called scalar with the value of 12345 in this case.

The text describes this quite clearly though as well as explaining why you would want to do this - hence my opening question of what you are looking for as an answer?

The code below demonstrates identical output from casting to object vs declaring as an object to begin with
<?php
$test_object = (object) array(
  'hello' => 'world',
  'nested' => array('key'=>'value'),
);
echo '<pre>';
print_r($test_object);
echo '</pre>';

class myObject {
    public $hello;
    public $nested;
    function __construct($hello, $nested)
    {
        $this->hello = $hello;
        $this->nested = $nested;
    }
}
$test_object = new myObject('World', array('key' => 'value'));
echo '<pre>';
print_r($test_object);
echo '</pre>';

class myOtherObject {
    public $scalar;

    function __construct($scalar)
    {
         $this->scalar = $scalar;
    }
}

$test_object = new myOtherObject(12345);
echo '<pre>';
print_r($test_object);
echo '</pre>';

$test_object = (object) 12345;
echo '<pre>';
print_r($test_object);
echo '</pre>';
?>

Open in new window

0
Ray PaseurCommented:
Historically, PHP is a loosely typed language.  This means that data types can (sometimes) assume different forms, depending on the context in which they are used.  For example, a string containing digits can be used as a string or as a number, depending on whether you want to write it into a data base, or use it in a computation.  This is part of PHP's funhouse history of trying to be the "easiest" language.  Refs here:
http://php.net/manual/en/language.types.php
http://php.net/manual/en/language.types.type-juggling.php
http://php.net/manual/en/types.comparisons.php

As computer science tries to bring some engineering principles into play, object oriented programming has been brought forth with the goal of allowing programmers to build something that is a reusable component.  For better or worse, OOP does not always play well with PHP's free and easy variable definitions.  Some kinds of automatic typecasting just don't make sense in the OOP environment, and now PHP programmers have to think about data types.  (Non-PHP programmers always had to think about data types, so this should not be seen as a burden.)

Complex data types, including arrays and objects are a little more difficult to pigeon-hole when you're trying to do automatic typecasting, and PHP does a stupefyingly bad job here.  What if you try to echo  a number?  You get a string.  But what if you try to echo an object?  PHP echo will try to convert the object to a string and will sometimes succeed or sometimes fail, creating a run-time situation that is a time bomb.  The only thing you don't know is when she will blow.  To try to bring some structure into the typecasting of objects as strings, PHP has introduced the magic method __toString() which is great, but is not always enforced by the language.  When programming languages do not enforce language requirements, programmers tend to make mistakes that create run-time errors.

The difference in addressing data in arrays and objects is frequently nothing more than syntax.  Arrays require you to write quotes and brackets; object properties use -> and do not require quotes and brackets.  For this reason alone, I find it easier to retrieve data base rows with fetch_object() methods.  And if you want to use HEREDOC notation for templating your HTML, the OO notation works better than the quoted array notation.

When you cast a PHP variable to an object via (object) PHP creates an instance of the built-in empty class, stdClass.  This class does not play well with echo.  When you try to echo an array, you get the word, "Array."  Neither result makes sense in the logic of trying to create human-usable output from an internal data structure.  So the programmer has to come up with something that shows the data from the array or object.  And that necessarily means the programmer has to think about the type of the variable and write programming accordingly.

Run this to see what's happening.

<?php // RAY_temp_rgb192.php
ini_set('display_errors', TRUE);
error_reporting(E_ALL);
echo '<pre>';


// SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28232334.html


// CREATE ARRAY AND OBJECT CAST FROM ARRAY
$test_arr = array(
  'hello' => 'world',
  'nested' => array('key'=>'value'),
);

$test_obj = (object) array(
  'hello' => 'world',
  'nested' => array('key'=>'value'),
);

// SHOW THE COMPLEX VARIABLES
var_dump($test_arr);
var_dump($test_obj);

// SHOW HOW TO ADDRESS AN ELEMENT OF THE ARRAY
echo $test_arr['hello'];

// SHOW HOW TO ADDRESS A PROPERTY OF THE OBJECT
echo $test_obj->hello;

// SHOW WHAT HAPPENS WHEN YOU ECHO THE ARRAY AND OBJECT
echo $test_arr;
echo $test_obj;

Open in new window

0
rgb192Author Commented:
Ray's answer:

from your explanation, echoing array is always 'ARRAY'
but why

echo $test_arr;
echo $test_obj;

and why cant object be echoed causing error
Catchable fatal error:  Object of class stdClass could not be converted to string in C:\wamp\www\oop_examples\ray-typcast.php on line 33

is there any way to try and catch object error
or how else to print the array and object
0
Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

rgb192Author Commented:
julianH:

I do not understand the difference between the two classes.

is one an object class and the other a scaler class


and
'World', array('key' => 'value')
passed in the class

versus
$scalar
0
Ray PaseurCommented:
For testing purposes, you can (and should) use var_dump() to print out any variable.  It will tell you the type, length, etc., and it will explore the data recursively.

The problem with PHP echo is that it was created a long time ago, before much thought was given to PHP arrays or any thought was given to PHP objects.  The problem with PHP arrays is that instead of creating a fatal error when you try to typecast them inappropriately, a years-ago decision was made to return the word Array.  Design mistake?  Probably.

I think you can extend the stdClass to add a __toString() method, but I've never tried it.  You would probably need to instantiate an object from the new class.  I would not expect typecasting to create an instance of anything other than the stdClass.

You can use try/catch with catchable errors.
0
Ray PaseurCommented:
Footnote: scalar != scaler
0
Slick812Commented:
hello, , you ask -"I do not understand the difference between the two classes., , , is one an object class and the other a scaler class"

But this question can NOT be answered, as YOU have decided that there are two different classes called "object class" and   "scaler class", but there is NO distinction or terminology or way to talk about your "object class" and   "scaler class", because these do not exist anywhere.

A short answer for your question for -
$object1 = (object) array( 'one' => 'hello',  'two' => "world",);
$object2 = (object) 12345;

is that Both of these produce an Object, not a Class, both of these make objects ($object1 , $object2) that are from the SAME CLASS definition the default PHP stdClass.

I doubt that my next explanation will mean much to you, BUT, PHP has little error control for typecasting as (object), instead, it will just add the "Default" property name of "scalar" to a default object creation of PHP stdClass using the property value for whatever is behind the (object) declaration, but WHY you ask? ?, because there absolutely has to be a property name for any property in an Object, since there is NO PROPERTY NAME Given in this -
$object2 = (object) 'This is a Value, but I do not have any Property Name';
PHP just uses the text of "scalar" for the property name, even though it makes no sense, but I guess it is a good of text name as any other? But It HAS TO USE SOMETHING for the PROPERTY NAME!

OK if you use an araay
$object1 = (object) array( 'one' => 'hello',  'two' => "world");
with KEY and Value, then PHP has something to use as a Property NAME AND a Property VALUE, so the "scalar"  is NOT used for this, but PHP is using the SAME method for for typecasting as (object) with BOTH OF THESE, with the information available during the typecasting as (object).
You can do var_export($test_object,TRUE)  or var_dump()  all day long, and it will not help you to understand what typecasting is doing, untill you understand some of the PHP method of typecasting as (object).

It may be for most developers, that  typecasting as (object), is NOT VERY USEFUL.
0
Ray PaseurCommented:
@Slick812:
It may be for most developers, that  typecasting as (object), is NOT VERY USEFUL.
Agreed.  I have never seen a professional programmer do that!  And I just scanned my teaching example library.  I have over 1/2 million lines of examples.  Not one of them contains (object) until I did it today to test the idea!
0
Julian HansenCommented:

I do not understand the difference between the two classes.
is one an object class and the other a scaler class

No - both are objects - a scalar is just a value like an int - denoting a simple type.

When casting a scalar (non-complex type) to an object PHP creates a class for you with a property called scalar set to the value of the variable you cast.

When you cast a complex type like an array to an object then PHP creates an object with properties matching the names of the elements in the complex type.

For example
<?php
$ctype = array("a"=>1, "b" => 2, "c" => 3);
$cobj = (object)$ctype;
echo "<pre>";
print_r($cobj);
echo "</pre>";
echo $cobj->a;
?>
However contstast that with
<?php
$ctype = array(1, 2, 3);
$cobj = (object)$ctype;
echo "<pre>";
print_r($cobj);
echo "</pre>";
echo $cobj->a;
?>
PHP will create the object for you but you won't be able to access the values in the array unless you cast it back again

The point being - cast should be used only when it adds value - and thought must be given to how it is used.
0
Ray PaseurCommented:
The requirement for a property name is not really a requirement, as this code example shows.  You can still use iterators to access the anonymous properties.  But in real life, nobody would ever do anything like this!  There is almost never any situation in which it makes sense to take a simple data structure and make it into a more complicated data structure, so just don't do that.

<?php
error_reporting(E_ALL);
echo "<pre>";

// CREATE AN ASSOCIATIVE ARRAY AND CAST IT AS AN OBJECT
$ctype = array("a"=>1, "b" => 2, "c" => 3);
$cobj = (object)$ctype;
var_dump($cobj);

// ECHO ONE OF THE PROPERTIES
echo PHP_EOL . "OBJECT PROPERTY 'a' CONTAINS: " . $cobj->a;
echo PHP_EOL;

// OVERWRITE THE VARIABLE WITH A NUMERICALLY INDEXED ARRAY AND CAST IT TO OBJECT
$ctype = array(1, 2, 3);
$cobj = (object)$ctype;
var_dump($cobj);

// OBVIOUSLY, THIS IS NOW AN UNDEFINED VARIABLE
echo $cobj->a;

// USE AN ITERATOR TO ACCESS THE ANONYMOUS PROPERTIES
foreach ($cobj as $key => $val)
{
    echo PHP_EOL . "KEY $key POINTS TO VAL $val";
}
echo PHP_EOL;

// CAST SOMETHING ELSE USELESS
$thing = (object)FALSE;
var_dump($thing);

// IS THIS TRUE OR FALSE?
if ($thing) echo PHP_EOL . "GOTCHA" . PHP_EOL;

// CAST A FLOATING POINT NUMBER AS AN OBJECT
$thing = (object)3.1416;
var_dump($thing);

// CAST AN OBJECT AS AN OBJECT
$thing = (object)$thing;
var_dump($thing);

Open in new window

0
rgb192Author Commented:
Julian:
second part of code
echo $cobj->a;
I tried
echo $cobj->1;

how could I echo variables?

Ray:

// OBVIOUSLY, THIS IS NOW AN UNDEFINED VARIABLE
echo $cobj->a;

is this a defined variable?
echo $cobj['a'];

Slick812:

is that Both of these produce an Object, not a Class, both of these make objects ($object1 , $object2) that are from the SAME CLASS definition the default PHP stdClass.

I do not understand how these are from the same class.
Have both these objects been instantiated?
0
Julian HansenCommented:
I tried
echo $cobj->1;

how could I echo variables?

You can't in this case - as Ray mentioned in his post you can iterate through the object and output the values - but it's like riding a bicyle by pedaling with your hands - just because you can do it does not mean it is a good idea.

The example was to illustrate a point of how often functionality is provided but it does not mean there is an acceptable use for the functionality. In this case the casting of an array with numeric keys to an object does work because the general case allows for the casting of any array to an object (which is potentially useful when associative arrays are being cast) - the side effect is that non-associative arrays will also allow a cast but will result in an object that is not useful.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ray PaseurCommented:
is this a defined variable?
echo $cobj['a'];
A more important and on-point question might be, "Is $cobj an array or an object?"  The bracket notation is used to address elements of an array.  The arrow notation is used to address properties of an object.

Conceptually, arrays and objects are very much the same, in that both of these data collections give us a single name that can be used to address a collection of individual data elements.  Unless you have methods in the object, there is usually a choice of whether to make objects or arrays.  For example, you can fetch the rows of a query results set as either arrays or objects.  If you choose objects, you get a syntax that is free of quote marks, making the data easier to use in templates like HEREDOC.

Both arrays and objects can be nested.  Objects can contain objects, arrays can contain arrays and each can contain the other.  You can make this very complicated and academic if you try.  

One of the most useful data constructs is an array of objects.  It's almost as good as having the tools of the associative array without the restriction that the keys be unique!  You can sort, insert, unset, and do all kinds of interesting things with arrays of objects.
0
Slick812Commented:
rgb192, , that entire lesson at "3 minute lynda.com tutorial transcript" which has this -  
"00:04      I'll start with the standard class, which is pretty generic,"

Please Notice this at 00:16
"A standard class is a generic class that can be created by typecasting a value as an object, like casting the string "hello, world" as an object."

You need to understand what the default PHP "standard class" is and what it means to create an object from it with code like this -
$object1 = new stdClass; // the PHP standard Class
I am sure that like all tutorials for PHP for stdClass they explain some about it, and you should have gotten some understanding from it!!

OK, you are completely Clueless for what "typecasting" means in computer programming, and you should have goggled "programming typecaste" or gone to WIKI to learn about that. However PHP is a typeless language, but PHP developers wanted to have PHP do stuff that the C Language does, and be able to do "typecasting", which is REQUIRED in C Language to change One variable type to another, because in C Language you CAN NOT use a string for an integer, or a DWORD (unsigned 32bit number) for an INTEGER, so sometimes you covert an integer to a dword by typecasting -
int1 = (int) dword1;// this Changes the DWORD type to an INTEGER type
Because in C Language everything using variables REQUIRES a TYPE, and ALL variables can ONLY be used if they match the type required. (this gives a general explanation, but there's more to it than this)

you can typecast in PHP but it is mostly USELESS, as PHP does not EVER TYPE it's variables. Some possible code -
$string1 = '12345'; // this is a string
$int1 = (int) $string1; // $int1 is now a NUMBER value12345,instead of a string;

Although it is USELESS, most CLASS-OBJECT tutorials tell some about typecasting to an object with (object), if you do not understand this, then skip over it, as you will NOT need it to do PHP programming with Objects

you ask - "I do not understand how these are from the same class. Have both these objects been instantiated? "
again you ask a questions that does not have a definite answer, If there is an Object then YES it has been  instantiated! ! ! If it was not  instantiated then there would not be an object.
The typecasting to an object with (object) will ALWAYS produce an object of stdClass, if there are NO CODE MISTAKES. Because there are not any other PHP classes that could be used. There is not really any explainable reason for why typecasting to an object with (object) does what it does (make a stdClass object), it is just how PHP was made to do, please accept this and move on.

In case you are bongled this code -
$object1 = (object) $String;
should never be written like that, Instead use the Correct way to do this as -
$object1 = new stdClass;
$object1->name = $String;
0
rgb192Author Commented:
thanks for typecasting object array information
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.