Hi internals,
Does anyone knows why json_encode ignores protected/public class members ?
I've searching about it on documentation an mailing lists but found
nothing but workarounds.
Until now I'm forced to change my classes to use public members when I
need to send a PHP object on e.g. AJAX responses. It would be nice if
json_encode also send those attributes or at least have a parameter to
whether send non-public attributes or not.
Thanks in advance.
Jaris.
--
Jarismar Chaves da Silva, M.Sc.
ADPLabs* Brazil**
*jarismar_silva@adplabs.com.br mailto:jarismar_silva@adplabs.com.br
http://www.adp.com
Until this gets fixed instead of declaring the properties public you can use
a encode method like this:
<?
class c1
{
protected $p1 = 'aa';
public $p2 = 'bb';
public function enc()
{
//print $this->p1;
return json_encode(get_object_vars($this));//this will encode the
protected var
}
}
$o = new c1;
print $o->enc();
?>
On Thu, Oct 9, 2008 at 3:54 PM, Jarismar Chaves da Silva <
jarismar_silva@adplabs.com.br> wrote:
Hi internals,
Does anyone knows why json_encode ignores protected/public class members ?
I've searching about it on documentation an mailing lists but found
nothing but workarounds.
Until now I'm forced to change my classes to use public members when I
need to send a PHP object on e.g. AJAX responses. It would be nice if
json_encode also send those attributes or at least have a parameter to
whether send non-public attributes or not.Thanks in advance.
Jaris.--
Jarismar Chaves da Silva, M.Sc.
ADPLabs* Brazil**
*jarismar_silva@adplabs.com.br mailto:jarismar_silva@adplabs.com.br
http://www.adp.com
protected/private class members. I mean, why we need this feature.
Vesselin Kenashkov wrote:
> Until this gets fixed instead of declaring the properties public you
> can use a encode method like this:
> <?
> class c1
> {
> protected $p1 = 'aa';
> public $p2 = 'bb';
> public function enc()
> {
> //print $this->p1;
> return json_encode(get_object_vars($this));//this will encode the
> protected var
> }
> }
> $o = new c1;
> print $o->enc();
> ?>
>
> On Thu, Oct 9, 2008 at 3:54 PM, Jarismar Chaves da Silva
>
> wrote:
>
> Hi internals,
>
> Does anyone knows why json_encode ignores protected/public class
> members ?
> I've searching about it on documentation an mailing lists but
> found nothing but workarounds.
> Until now I'm forced to change my classes to use public members
> when I need to send a PHP object on e.g. AJAX responses. It would
> be nice if json_encode also send those attributes or at least have
> a parameter to whether send non-public attributes or not.
>
> Thanks in advance.
> Jaris.
>
> --
>
> *Jarismar Chaves da Silva, M.Sc.*
>
> *ADP**Labs** Brazil**
> *jarismar_silva@adplabs.com.br
>
>
> http://www.adp.com
>
>
--
*Jarismar Chaves da Silva, M.Sc.*
*ADP**Labs** Brazil**
*+55 51 3327 1491 – Direct
+55 51 9947 3613 – Mobile
jarismar_silva@adplabs.com.br
http://www.adp.com
This message and any attachments are intended only for the use of the
addressee and may contain information that is privileged and
confidential. If the reader of the message is not the intended recipient
or an authorized representative of the intended recipient, you are
hereby notified that any dissemination of this communication is strictly
prohibited. If you have received this communication in error, please
notify us immediately by e-mail and delete the message and any
attachments from your system.
On Thursday 09 October 2008 15:13:43 Jarismar Chaves da Silva wrote:
Ok, nice solution, but I still don't see why json_encode ignores
protected/private class members. I mean, why we need this feature.
Because, in theory, it shouldn't even be able to see those members?
Regards,
Stefan
Ok, nice solution, but I still don't see why json_encode ignores
protected/private class members. I mean, why we need this feature.Because, in theory, it shouldn't even be able to see those members?
Stefan's right. Unless you are in the local scope or inheriting the
object you shouldn't be able to see those variables. And I have yet to
see
classs Name extends json_decode($jsonValues) { }
That's the point in having access modifiers. Unless I'm mistaking
there's no bug there.
--
Slan,
David
Ok, nice solution, but I still don't see why json_encode ignores
protected/private class members. I mean, why we need this feature.Because, in theory, it shouldn't even be able to see those members?
Stefan's right. Unless you are in the local scope or inheriting the
object you shouldn't be able to see those variables. And I have yet to
seeclasss Name extends json_decode($jsonValues) { }
That's the point in having access modifiers. Unless I'm mistaking
there's no bug there.
well .. i think this is at least the common use case. then again, json
is an encoding format, and i expect that i can get the same object
state by decoding. so the expectation to also get non public
properties in the json encoded string is not totally crazy.
however changing this at this point would be a huge security issue, so
if at all, it would need to be handled by an optional parameter that
defaults to false.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
I still don't see why json_encode ignores protected/private class
members. I mean, why we need this feature.Because, in theory, it shouldn't even be able to see those members?
Stefan's right. Unless you are in the local scope or inheriting the
object you shouldn't be able to see those variables. And I have yet to
seeclasss Name extends json_decode($jsonValues) { }
That's the point in having access modifiers. Unless I'm mistaking
there's no bug there.
well .. i think this is at least the common use case. then again, json
is an encoding format, and i expect that i can get the same object
state by decoding. so the expectation to also get non public
properties in the json encoded string is not totally crazy.
I'd have thought the common use case is that you only want the public
class members, unless you're inside the class. It could make sense to
have an additional "member visibility filter" flag of some kind,
defaulting to public visibility, but can be set to encode protected or
private members as well (for backwards compatibility). It would be nice
(I suppose) if it automatically encoded private/protected members as
well depending on context, but I'm not sure how complex it would be to
add, and how intuitive it would be.
I think that the solution given earlier is best though - explicitly
encoding the array returned by get_object_vars()
.
But when using json_encode I believe the developer wants to transfer
the complete object state, just like when using serialize.
Serialize does see private/protected class members, while json_encode not.
If you want to serialize an object, then use the appropriate function. I
think thatjson_encode()
has the correct behaviour - encoding only the
publicly-visible structure of an object. They have fundamentally
different aims. If you want to expose data to an external source (e.g.
JavaScript) then surely it would make sense for it to be a public class
member? Why would you not want your PHP code to be able to access it?
Javascript does not have class-accessors so why not convert
protected/private to public javascript attributes.
That's true, although it does have convention that members beginning
with an underscore are generally understood to be treated as
private/protected.
Dave
But when using json_encode I believe the developer wants to transfer
the complete object state, just like when using serialize.
Serialize does see private/protected class members, while
json_encode not.
If you want to serialize an object, then use the appropriate
function. I
think thatjson_encode()
has the correct behaviour - encoding only the
publicly-visible structure of an object. They have fundamentally
different aims. If you want to expose data to an external source (e.g.
JavaScript) then surely it would make sense for it to be a public
class
member? Why would you not want your PHP code to be able to access it?
Because JSON is a language agnostic serialization format. Again I
agree that in the usual situation you only want public, but the other
use case is also quite legit. Having to add such a "hack" into every
class is not very useable, especially until we have traits.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
On Thursday 09 October 2008 15:31:54 Lukas Kahwe Smith wrote:
well .. i think this is at least the common use case. then again, json
is an encoding format, and i expect that i can get the same object
state by decoding. so the expectation to also get non public
properties in the json encoded string is not totally crazy.
Well, you lose the information about the class anyway, so there is no way to
decode it to the previous state without implementing it yourself, and in
order to set private/protected attributes, you have to implement it as a
method ... and if you do that, it's natural that you also do a member
function that does the encoding, so the round-trip argument doesn't really
work.
however changing this at this point would be a huge security issue, so
if at all, it would need to be handled by an optional parameter that
defaults to false.
That would be unclean. If it's implemented in some way, json_encode should
look for the implementation of some interface (JSONEncodable or something)
providing encoding/decoding methods (similar to __sleep/__wakeup).
Regards,
Stefan
however changing this at this point would be a huge security issue, so
if at all, it would need to be handled by an optional parameter that
defaults to false.That would be unclean. If it's implemented in some way, json_encode should
look for the implementation of some interface (JSONEncodable or something)
providing encoding/decoding methods (similar to __sleep/__wakeup).
I must say that does sound like a very elegant way of doing things. Then
the default for __json_encode() would encode the public members, and
there would be no default __json_decode(), I suppose.
Dave
Yes, it like it too. Just like an OOP should be.
Dave Ingram wrote:
however changing this at this point would be a huge security issue, so
if at all, it would need to be handled by an optional parameter that
defaults to false.That would be unclean. If it's implemented in some way, json_encode should
look for the implementation of some interface (JSONEncodable or something)
providing encoding/decoding methods (similar to __sleep/__wakeup).I must say that does sound like a very elegant way of doing things. Then
the default for __json_encode() would encode the public members, and
there would be no default __json_decode(), I suppose.Dave
--
Jarismar Chaves da Silva, M.Sc.
ADPLabs* Brazil**
*+55 51 3327 1491 -- Direct
+55 51 9947 3613 -- Mobile
jarismar_silva@adplabs.com.br mailto:jarismar_silva@adplabs.com.br
http://www.adp.com
This message and any attachments are intended only for the use of the
addressee and may contain information that is privileged and
confidential. If the reader of the message is not the intended recipient
or an authorized representative of the intended recipient, you are
hereby notified that any dissemination of this communication is strictly
prohibited. If you have received this communication in error, please
notify us immediately by e-mail and delete the message and any
attachments from your system.
Stefan Walk wrote:
That would be unclean. If it's implemented in some way, json_encode should
look for the implementation of some interface (JSONEncodable or something)
providing encoding/decoding methods (similar to __sleep/__wakeup).
Looking at our current JSON implementations, such an interface would be
very very welcome. If at all possible something like JSONDecodable would
be great as well, for restoring class members from json.
Ron
Ron Rademaker wrote:
Stefan Walk wrote:
That would be unclean. If it's implemented in some way, json_encode
should look for the implementation of some interface (JSONEncodable
or something) providing encoding/decoding methods (similar to
__sleep/__wakeup).
Looking at our current JSON implementations, such an interface would
be very very welcome. If at all possible something like JSONDecodable
would be great as well, for restoring class members from json.
I'm thinking about getting involved with some PHP internals, so this
might be as good a place to start as any, unless someone else is
particularly interested or motivated. Having said that, I had first
planned to make some minor changes to the apache2 SAPI to solve a
long-requested feature. I haven't yet looked into why the Apache hasn't
been implemented yet though, so I didn't want to propose it yet.
Dave
I agree with you.
But when using json_encode I believe the developer wants to transfer the
complete object state, just like when using serialize.
Serialize does see private/protected class members, while json_encode not.
Javascript does not have class-accessors so why not convert
protected/private to public javascript attributes.
Stefan Walk wrote:
On Thursday 09 October 2008 15:13:43 Jarismar Chaves da Silva wrote:
Ok, nice solution, but I still don't see why json_encode ignores
protected/private class members. I mean, why we need this feature.Because, in theory, it shouldn't even be able to see those members?
Regards,
Stefan
--
Jarismar Chaves da Silva, M.Sc.
ADPLabs* Brazil**
*jarismar_silva@adplabs.com.br mailto:jarismar_silva@adplabs.com.br
http://www.adp.com
Jarismar Chaves da Silva wrote:
I agree with you.
But when using json_encode I believe the developer wants to transfer the
complete object state, just like when using serialize.
Serialize does see private/protected class members, while json_encode not.
Javascript does not have class-accessors so why not convert
protected/private to public javascript attributes.
In theory only the public members are relevant to anyone except the
object itself. If you need information about private/protected members
you are either using the wrong visibility for your variables or using
json for something it's not supposed to do.
-- Rodrigo Saboya
2008/10/9 Rodrigo Saboya rodrigo.saboya@bolsademulher.com:
Jarismar Chaves da Silva wrote:
I agree with you.
But when using json_encode I believe the developer wants to transfer the
complete object state, just like when using serialize.
Serialize does see private/protected class members, while json_encode not.
Javascript does not have class-accessors so why not convert
protected/private to public javascript attributes.In theory only the public members are relevant to anyone except the object
itself. If you need information about private/protected members you are
either using the wrong visibility for your variables or using json for
something it's not supposed to do.-- Rodrigo Saboya
--
A simply userland solution would be to use an abstract base class with
json_encode()
/json_decode() as public final methods. All classes
needing to support json_encode/json_decode would simply need to extend
from this base class.
No need to add even more "magic" to the base stdClass.
Richard.
--
Richard Quadling
Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731
"Standing on the shoulders of some very clever giants!"
Rodrigo Saboya wrote:
Jarismar Chaves da Silva wrote:
I agree with you.
But when using json_encode I believe the developer wants to transfer
the complete object state, just like when using serialize.
Serialize does see private/protected class members, while json_encode
not.
Javascript does not have class-accessors so why not convert
protected/private to public javascript attributes.In theory only the public members are relevant to anyone except the
object itself. If you need information about private/protected members
you are either using the wrong visibility for your variables or using
json for something it's not supposed to do.
Yes, of course. But currently json_encode ignores the attributes even if
the call is from inside the class.
<?php
class Person {
protected $name;
public function __construct($sName) {
$this->name = $sName;
}
public function toJSON() {
return json_encode($this);
}
}
$person = new Person('jaris');
print $person->toJSON(); // ==> will print an empty object e.g. {}
?>
I don't know if I'm using json_encode for something it's not supposed to
do. I'm using it to serialize an object to send it to another
runtime-environment in response to an remote call, just like what I can
do with SOAP, REST or RMI. In this context I don't see much sense in
preventing protected/private data from being transfered.
Regards,
Jaris.
-- Rodrigo Saboya
--
Jarismar Chaves da Silva, M.Sc.
ADPLabs* Brazil**
*jarismar_silva@adplabs.com.br mailto:jarismar_silva@adplabs.com.br
http://www.adp.com
2008/10/10 Jarismar Chaves da Silva jarismar_silva@adplabs.com.br:
Rodrigo Saboya wrote:
Jarismar Chaves da Silva wrote:
I agree with you.
But when using json_encode I believe the developer wants to transfer the
complete object state, just like when using serialize.
Serialize does see private/protected class members, while json_encode
not.
Javascript does not have class-accessors so why not convert
protected/private to public javascript attributes.In theory only the public members are relevant to anyone except the object
itself. If you need information about private/protected members you are
either using the wrong visibility for your variables or using json for
something it's not supposed to do.Yes, of course. But currently json_encode ignores the attributes even if the
call is from inside the class.
<?php
class Person {
protected $name;public function __construct($sName) {
$this->name = $sName;
}public function toJSON() {
return json_encode($this);
}
}$person = new Person('jaris');
print $person->toJSON(); // ==> will print an empty object e.g. {}
?>I don't know if I'm using json_encode for something it's not supposed to do.
I'm using it to serialize an object to send it to another
runtime-environment in response to an remote call, just like what I can do
with SOAP, REST or RMI. In this context I don't see much sense in preventing
protected/private data from being transfered.Regards,
Jaris.-- Rodrigo Saboya
--
Jarismar Chaves da Silva, M.Sc.
ADPLabs* Brazil**
*jarismar_silva@adplabs.com.br mailto:jarismar_silva@adplabs.com.br
http://www.adp.com
Let's just for example say that class X has the username and password
values for the login system.
You've made them private as only this class should access them.
How are you going to stop the json_encode()
from seeing them and
passing them on.
--
Richard Quadling
Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731
"Standing on the shoulders of some very clever giants!"
Hi Jaris:
I don't know if I'm using json_encode for something it's not supposed to
do. I'm using it to serialize an object to send it to another
runtime-environment in response to an remote call, just like what I can
do with SOAP, REST or RMI. In this context I don't see much sense in
preventing protected/private data from being transfered.
So you are accessing the class from outside. This is exactly the
situation where private and protected should not be visible. It's just
like you're trying to access private properties from the wrong scope in
PHP itself:
<?php
class c {
private $p = 'hidden';
}
$o = new c;
echo $o->p; // This will fail, as it should.
You need to change your architecture to do what you want.
--Dan
--
T H E A N A L Y S I S A N D S O L U T I O N S C O M P A N Y
data intensive web and database programming
http://www.AnalysisAndSolutions.com/
4015 7th Ave #4, Brooklyn NY 11232 v: 718-854-0335 f: 718-854-0409
Hi,
So I guess the conclusion is:
Create a feature request ticket, take the information from this thread
and put it into the ticket .. and ideally write a patch yourself or
motivate someone else ..
regards,
Lukas