473,405 Members | 2,160 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Array property of object with __get and __set - is this a bug?

Hi All,

I'm reasonably proficient with C#, and am starting with php5. I was happy
to learn of the __get and __set methods, but am encountering a problem using
them to set an object property of type "array".

Below is a simple example of the problem I'm having with a sample object
"Article", which has an array property "authors". As you can see, I can't
even use standard php array syntax to set a single author, even though the
same syntax outside of the object works perfectly.

Am I doing something wrong here, or is this a php5 bug?

TIA,

JON

---------------------------------------
//test with normal array
$array = array();
$array[] = "Mr Jones";
print $array[0] . "<br>";

// expected result: "Mr Jones"
// actual result: "Mr Jones"

//test with array property
$article = new Article();
$article->title = "my title";
$article->authors[] = "Mr Smith";
print $article->authors[0] . "<br>";

// expected result: "Mr Smith"
// actual result: "Notice: Undefined offset: 0"

//diagnosis: authors array is *not* being filled.
// var_dump($article->authors);
// gives
// result: array(0) { }

class Article
{
protected $properties = array(
'title' => "",
'authors' => array()
);

public function __construct()
{
}

public function __get($property)
{
if( array_key_exists($property, $this->properties) )
{
return $this->properties[$property];
}
else
{
throw new Exception();
}
}

public function __set($property, $value)
{
if( array_key_exists($property, $this->properties) )
{
$this->properties[$property] = $value;
}
else
{
throw new Exception();
}
}
}

Nov 7 '05 #1
5 5518
Not really a bug..more a difference in the way __get and __set are
handled. Remember that when you use these, something like:

$x = $obj->y

does something slightly different than what you expect. Consider the
following:

function makeArray() {
$r = array(1, 2, 3, 4);
return $r;
}

Could you then write something like this:

echo makeArray()[2];

No, because makeArray is a function, not a reference or variable. The
same thing happens when you use __get() and __set(). Although it looks
like regular property accessing and setting, it really isn't.

This is the same reason you can't use overloaded __get() and __set with
empty(), unset(), etc. (well, now you can overload those, too).

The simplest solution to your problem is to pull out the array before
you try and access or set it's element:

$article = new Article();
$article->title = "my title";
$authors = array("Mr. Smith");
$article->authors = $authors;
print $authors[0] . "<br>";

Nov 7 '05 #2
ZeldorBlat said the following on 07/11/2005 14:34:
Not really a bug..more a difference in the way __get and __set are
handled. Remember that when you use these, something like:

$x = $obj->y

does something slightly different than what you expect. Consider the
following:

function makeArray() {
$r = array(1, 2, 3, 4);
return $r;
}

Could you then write something like this:

echo makeArray()[2];

No, because makeArray is a function, not a reference or variable.


Actually, this is a limitation of PHP. In C, C++, C# and Java, the
equivalent of the above code works fine.

--
Oli
Nov 7 '05 #3
On 7 Nov 2005 06:34:47 -0800, "ZeldorBlat" <ze********@gmail.com>
wrote:
No, because makeArray is a function, not a reference or variable. The
same thing happens when you use __get() and __set(). Although it looks
like regular property accessing and setting, it really isn't.


Well you're right that you can't do someFunction()[0] but array access
syntax does work for __get and _set. Try this in PHP5 and you'll get
the desired result:

class Test
{
public function __get($name) {
return Array('hello', 'world');
}
public function blah()
{
return Array('hello', 'world');
}
}

$test = new Test();
echo $test->whatever[0];
// displays 'hello'

The original posters problem is entirely different.

Nov 7 '05 #4
On Mon, 7 Nov 2005 10:48:57 -0000, "Jon Maz"
<jo****@surfeu.no.spam.de> wrote:
Hi All,

I'm reasonably proficient with C#, and am starting with php5. I was happy
to learn of the __get and __set methods, but am encountering a problem using
them to set an object property of type "array".

Below is a simple example of the problem I'm having with a sample object
"Article", which has an array property "authors". As you can see, I can't
even use standard php array syntax to set a single author, even though the
same syntax outside of the object works perfectly.

Am I doing something wrong here, or is this a php5 bug?
The problem is that arrays are values in PHP. So when you return an
array from a function (or assign it to variable) you're really
returing/assigning a copy of the array.
//test with array property
$article = new Article();
$article->title = "my title";
$article->authors[] = "Mr Smith";


This line adds "Mr Smith" to a copy of the authors array (as returned
by the __get function) and not the original array.

Your best bet is to use an ArrayObject rather than an array. It works
just like an array but, like all objects in PHP5, it's passed by
reference and should work as you expect.

Later,

Nov 7 '05 #5
Hi All,

Thanks for the responses, they've helped me understand what's going on.

-------------

I think Oli hit the nail on the head when he wrote:
Could you then write something like this:
echo makeArray()[2];
No, because makeArray is a function, not a reference or variable.
Actually, this is a limitation of PHP. In C, C++, C# and Java, the
equivalent of the above code works fine.
I was indeed expecting PHP to work just like C#. Does anybody know if
there are plans to change this PHP behavior? Is this regarded as a bug
or a feature? (My vote is for bug).

-------------

In the end I have decided to solve the problem by replacing my properties
of type array() with properties of type CollectionBase, as found
here: http://coding.mu/archives/2003/08/09...lection-class/. I think
this is the solution Wayne was suggesting when he proposed using an
object instead of an array.

I decided to switch to this Collection object before Wayne gave the
ArrayObject tip. I'd never heard of ArrayObject, but have found some
useful info on it. Urls here in case they help anyone else:

http://www.sitepoint.com/article/php...dard-library/2
http://www.ramikayyali.com/archives/...2/25/iterators
http://www.php.net/~helly/php/ext/sp...rayObject.html
http://www.devshed.com/index2.php?op...ge=0&hide_js=1

-------------

Finally, in my digging around on the net I found the following. I don't
100% follow the argument here, but it sounds like this guy is discussing
the same issue I came across (true?).

http://uk.php.net/manual/en/language...verloading.php A few things I've found about __get()...

First off, if you use $obj-> getOne-> getAnother, both intended
to be resolved by __get, the __get() function only sees the first
one at first. You can't access the second one. You can, however,
return the pointer to an object that can handle the second one.
In short, you can have the same class handle both by returning a
new object with the data changed however you see fit.

Secondly, when using arrays like: $obj-> getArray["one"], only
the array name is passed on to __get. However, when you return
the array, PHP treats it just as it should. THat is, you'd have
to make an array with the index of "one" in __get in order to see
any results. You can also have other indexes in there as well.

Also, for those of you like me, I've already tried to use
func_get_args to see if you can get more than just that one.

If you're like me and were hoping you could pass some sort of
argument onto __get in order to help gather the correct data,
you're out of look. I do recommend using __call though. You could
easily rig __call up to react to certain things, like: $account->
properties( "type" ); , which is my example. I'm using DOM for
data storage (for now), and I'm trying to make an interface
that'll let me easily switch to something else - MySQL, flat
file, anything. This would work great though!


-------------

Thanks once again for all the help,

JON
Nov 9 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: Scott Auge | last post by:
I am looking for comments on something that lets me abstract database updates in an object. Lemme explain what I am thinking: Lets say I have an object Person with... SetFirstName()...
26
by: JGH | last post by:
How can I check if a key is defined in an associative array? var users = new array(); users = "Joe Blow"; users = "John Doe"; users = "Jane Doe"; function isUser (userID) { if (?????)
5
by: Denis Perelyubskiy | last post by:
Hello, I need to make an array of elements accross forms. My javascript skills, as evident from this question, are rather rudimentary. I tried to make an associative array and index it with...
47
by: VK | last post by:
Or why I just did myArray = "Computers" but myArray.length is showing 0. What a hey? There is a new trend to treat arrays and hashes as they were some variations of the same thing. But they...
35
by: VK | last post by:
Whatever you wanted to know about it but always were affraid to ask. <http://www.geocities.com/schools_ring/ArrayAndHash.html>
7
by: Robert Mark Bram | last post by:
Hi All! How do you get the length of an associative array? var my_cars= new Array() my_cars="Mustang"; my_cars="Station Wagon"; my_cars="SUV"; alert(my_cars.length);
38
by: VK | last post by:
Hello, In my object I have getDirectory() method which returns 2-dimentional array (or an imitation of 2-dimentional array using two JavaScript objects with auto-handled length property - please...
21
by: yeti349 | last post by:
Hi, I'm using the following code to retrieve data from an xml file and populate a javascript array. The data is then displayed in html table form. I would like to then be able to sort by each...
2
by: JJA | last post by:
I'm looking at some code I do not understand: var icons = new Array(); icons = new GIcon(); icons.image = "somefilename.png"; I read this as an array of icons is being built. An element of...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.