Closed yuya-miyake closed 10 years ago
Hmm.... Yeah, isset is probably not a good idea. I'll have a look.
Great! Thank you very much (and sorry my wrong usage of array_key_exists()...). BTW, I noticed that isset() is the implementation of isset() functinality on inaccessible properties, so it's ok to use isset() in isset(), isn't it?
@yuya-miyake correct, @WanWizard I think the one in __isset should be reverted, agreed?
Well, that depends.
If it's your point of view that when a property is set with the value null
(which I think was why this issue was opened) the __isset() method should return true, you can no use isset() there either.
According to PHP manual, I think this is correct behavior.
$model = Some_Model_Crud::forge(array('property_name' => NULL));
$model->property_name; // NULL without errors. This is the reason why I opened this issue.
isset($model->property_name); // FALSE
http://jp.php.net/manual/en/function.isset.php
isset
determines if a variable is set and is not NULL.
which is why I used array_key_exists()
in __isset()
. So it returns true
instead of false
.
@WanWizard the array_key_exists
is correct to for the __get
method, not for the __isset
one, I've reverted that part. isset
is expected to be false on null.
@FrenkyNet that's what I want to explain. Thanks.
I understand that from a PHP point of view, you want like to have it this way.
However, consider the following. Say I have a table, and in this table the following column:
property NULL DEFAULT 'A'
And this bit of code:
public function something($property = null)
{
$model = Model_Something::forge();
$model->property = $property;
// ....
if (something)
{
$model->property = null;
}
// ...
if ( ! isset($model->property))
{
$model->property = 'B';
}
$model->save();
}
What is stored in the property column of the record? And what would you expect to be stored?
I would expect NULL to be stored, since NULL is a valid value for the column. But with Model_Crud's isset behaving like a standard isset(), 'B' will be saved.
And say I have this code:
public function something($property = null)
{
$model = Model_Something::forge();
$model->property = $property;
// ....
if (something)
{
unset($model->property);
}
// ...
if ( ! isset($model->property))
{
$model->property = 'B';
}
$model->save();
}
Now I would expect 'B' to be stored, when the property is explicitly unset.
@WanWizard I would expect it to be 'B'
?
If NULL is a valid value, you can never see the difference between "not there" and "=== null".
// this will save NULL
$model->property = null;
$model->save();
// this will save 'A'
unset($model->property);
$model->save();
How can I distinguish between those two values before I call save?
Indeed. There is no way to see the difference.
I guess property_exists
is supposed to be the way, but it does not work with magically accessible properties using get magic method.
I've no idea what is the best way, but in my opinion, `issetshould satisfy
isset` specification at least.
Thank you for your understandable explanations.
I still have a problem with it, because with the column definition in my example, there is a difference to what is stored in the record, based on whether the property value exists and is null
, or the property value is absent from $this->data
.
So imo this leads to possible unexpected behaviour, with no way of checking or validating it.
p.s. a request to properly fix this is open since 2008, with the usual response from the PHP community: nothing.
@WanWizard I agree with you. This is messy problem.
I tried:
got:
FuelPHP 1.7.1's Model_Crud::__get():
and I think it should be
I may overlook something. Should I write like below anytime?
Thanks.