FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » Imported messages » comp.lang.php » out of sheer curiosity...
Show: Today's Messages :: Polls :: Message Navigator
Switch to threaded view of this topic Create a new topic Submit Reply
Re: out of sheer curiosity... [message #177619 is a reply to message #177613] Tue, 10 April 2012 21:57 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jerry Stuckle schrieb:

> Although not a separate entity, the parent is still considered an
> object. You can, for instance, call public methods which are defined in
> the parent but not the child. Those methods will operate on the parent,
> just as if you had a parent object.

Hm. Makes sense.

> So basically what you have is "dual identity" - the object is considered
> both a parent and a child, depending on the context.

Yes, thinking more about it, it becomes a bit clearer. A child is also
an instance of all of its parent classes.

> And the parent's constructor is responsible for constructing the parent
> object; the child is only responsible for constructing the child object.

So the parent has a "private part" and the child has a "private part",
but they might also have a "shared part" ("protected") and there both
child and parent are responsible.

If the child overwrites a parent method, this will also affect the
parent since $this->method() will refer to the child's method, even if
called from a method defined in the parent class.

> This is actually quite important. This allows you to change the
> implementation (code and private variables) of the parent object without
> affecting any child objects.

So if there is no "shared part" between parent and child, does that mean
the child class should not have been derived from the parent in the
first place? Like "nothing to share -- nothing to inherit"?

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: out of sheer curiosity... [message #177620 is a reply to message #177616] Tue, 10 April 2012 22:13 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jerry Stuckle schrieb:

> I no longer even try to store objects in the session. It's hopeless.

Why? I never had any real problems with storing objects in the session.
Or maybe I was just lucky ;-)

> For instance - what if one of the things your object needs is a database
> connection? And what if you have several objects using that same
> connection? There is no way to pass an existing database connection to
> __wakeup(). You either have to use a global variable, restricting
> variable names in the rest of your code and limiting flexibility, or
> create a new connection in the __wakeup() call or remember to call
> another method to set the database connection after unserializing the
> object.

MyDatabaseSingleton::getInstance() ?

> None are good answers - but all could be easily handled with proper use
> of constructors.

And how would a "proper use of constructors" solve the above problem?
Even if unserialize() called __construct(), you would have no chance to
pass any arguments to the constructor.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: out of sheer curiosity... [message #177621 is a reply to message #177618] Tue, 10 April 2012 23:00 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jerry Stuckle schrieb:

[__sleep()]
> It can also be called after __wakeup(), i.e. if an unserialized object
> is serialized again.

Yes, but that would start a new "sleep cycle". You have to go to sleep
*before* you can wake up again.

> OK, now - one of the members of the object is a reference to a database
> connection object. How are you going to set that in your __wakeup() call?

I would put all the objects referencing the database object along with
the database object in a container object and serialize that. After
unserializing, the objects will again reference the same database
object. No need for __wakeup() here.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: out of sheer curiosity... [message #177622 is a reply to message #177617] Tue, 10 April 2012 23:43 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 4/10/2012 5:30 PM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
> [setting data on object before constructor is called]
>> I agree that it "feels wrong", but is perfectly valid. There are other
>> examples - for instance in Java and C++, the vase class constructor is
>> called before the derived class constructor.
>
> The base constructor, okay, yes. But setting data on the object,
> possibly invoking __set() which, in turn might (need to) do things
> requiring prior object initialization?
>

That is correct. That way __set() does not need to check to see if the
object has been initialized already.

> [PDO does not use __set_state()]
>> Possibly for future use? Most of PDO was written before __set_state()
>> was added, so maybe newer versions will use it.
>
> Hm, maybe. Meanwhile I think I can live with the fact that the
> constructor is called after setting the data. It's just something one
> must know and remember...
>
> Greetings,
> Thomas
>


--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: out of sheer curiosity... [message #177623 is a reply to message #177619] Tue, 10 April 2012 23:50 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 4/10/2012 5:57 PM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
>> Although not a separate entity, the parent is still considered an
>> object. You can, for instance, call public methods which are defined
>> in the parent but not the child. Those methods will operate on the
>> parent, just as if you had a parent object.
>
> Hm. Makes sense.
>
>> So basically what you have is "dual identity" - the object is
>> considered both a parent and a child, depending on the context.
>
> Yes, thinking more about it, it becomes a bit clearer. A child is also
> an instance of all of its parent classes.
>
>> And the parent's constructor is responsible for constructing the
>> parent object; the child is only responsible for constructing the
>> child object.
>
> So the parent has a "private part" and the child has a "private part",
> but they might also have a "shared part" ("protected") and there both
> child and parent are responsible.
>

Generally, protected variables are frowned upon. Remember - ANYTHING
exposed outside the class can never be changed once the class is put
into production. You don't know how it will affect other classes.

Also, protected member variables leave the possibility open that a child
class can place an invalid value in it, potentially corrupting the base
class.

Private members (both variables and methods) and the code in the methods
are never available outside the class. As long as the result is the
same, how the class is implemented is immaterial.

This can be very handy when prototyping, for instance. You can create a
"quick and dirty" implementation of the class and use it. Later you can
come back and clean it up, making it more efficient, etc.

> If the child overwrites a parent method, this will also affect the
> parent since $this->method() will refer to the child's method, even if
> called from a method defined in the parent class.
>

Nope. If it's important to the parent, then the child's method should
call the parent's method. But many times I've had methods in the child
class which don't call the parent method for various reasons.

>> This is actually quite important. This allows you to change the
>> implementation (code and private variables) of the parent object
>> without affecting any child objects.
>
> So if there is no "shared part" between parent and child, does that mean
> the child class should not have been derived from the parent in the
> first place? Like "nothing to share -- nothing to inherit"?
>
> Greetings,
> Thomas
>

There is always something to inherit - the public interface. But the
child class should always be a more specific instance of the parent
class. For instance, Person->Employee would be ok, because Employee is
a more specific instance of Person. However, Employee->Contractor would
not - a contractor is not an employee.

The Person class can have private members for name, address, etc.
Employee would have additional fields such as start_date, employee_id, etc.

And from Employee you could derive Manager.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: out of sheer curiosity... [message #177624 is a reply to message #177620] Tue, 10 April 2012 23:53 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 4/10/2012 6:13 PM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
>> I no longer even try to store objects in the session. It's hopeless.
>
> Why? I never had any real problems with storing objects in the session.
> Or maybe I was just lucky ;-)
>
>> For instance - what if one of the things your object needs is a
>> database connection? And what if you have several objects using that
>> same connection? There is no way to pass an existing database
>> connection to __wakeup(). You either have to use a global variable,
>> restricting variable names in the rest of your code and limiting
>> flexibility, or create a new connection in the __wakeup() call or
>> remember to call another method to set the database connection after
>> unserializing the object.
>
> MyDatabaseSingleton::getInstance() ?
>

What if you don't want a singleton? Many times I've had the need to
access different databases, for instance. You are limiting the
versatility of the class.

>> None are good answers - but all could be easily handled with proper
>> use of constructors.
>
> And how would a "proper use of constructors" solve the above problem?
> Even if unserialize() called __construct(), you would have no chance to
> pass any arguments to the constructor.
>
> Greetings,
> Thomas
>

By definition you can pass arguments to the constructor. That's why
unserialize() is not a good implementation.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: out of sheer curiosity... [message #177625 is a reply to message #177621] Tue, 10 April 2012 23:54 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 4/10/2012 7:00 PM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
> [__sleep()]
>> It can also be called after __wakeup(), i.e. if an unserialized object
>> is serialized again.
>
> Yes, but that would start a new "sleep cycle". You have to go to sleep
> *before* you can wake up again.
>
>> OK, now - one of the members of the object is a reference to a
>> database connection object. How are you going to set that in your
>> __wakeup() call?
>
> I would put all the objects referencing the database object along with
> the database object in a container object and serialize that. After
> unserializing, the objects will again reference the same database
> object. No need for __wakeup() here.
>
> Greetings,
> Thomas
>

No, because the database objects themselves will rely on external
resources which are not serialized. You have the same problem as before.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: out of sheer curiosity... [message #177626 is a reply to message #177610] Wed, 11 April 2012 08:40 Go to previous messageGo to next message
M. Strobel is currently offline  M. Strobel
Messages: 386
Registered: December 2011
Karma: 0
Senior Member
Am 10.04.2012 23:08, schrieb Jerry Stuckle:
> On 4/10/2012 12:54 PM, M. Strobel wrote:
>> Am 10.04.2012 13:28, schrieb Thomas Mlynarczyk:
>>> M. Strobel schrieb:
>>>
>>>> Now PDO comes in. When getting a query result as object your constructor is called
>>>> *after* the properties are set.
>>>
>>> Really? That would be very strange indeed.
>>>
>>> [minutes later]
>>> I just tested it and it is indeed as you state. Thanks for pointing that out -- is
>>> this documented?
>>>
>>>> I found it quite annoying to have an exception from the rule. But thinking more
>>>> about
>>>> it I found out they had a choice of either calling __construct() after setting the
>>>> data, or to define another magic method like __pdoconstruct() to give the programmer
>>>> a chance to adapt the init process to the data.
>>>
>>> I don't quite follow you here. Why did they have no choice? I don't see why they
>>> (c|sh)ould not call the constructor before setting the data. After all, that would be
>>> the only logical and sensible thing to do. If you would do this "manually", you would
>>> do it like this:
>>>
>>> foreach ( $rows as $row ):
>>> $item = new MyClass( 'foo', 'bar' );
>>> foreach ( $row as $name => $value ):
>>> $item->$name = $value;
>>> endforeach;
>>> $result[] = $item;
>>> endforeach;
>>>
>>
>> Meanwhile I have more ideas about choices.
>>
>> The correct way would have been to pass the row to the constructor. This would have
>> required a matching parameter definition for the constructor, and the corresponding
>> code, quite error prone.
>>
>
> Yes, that's how C++ does it, for instance (overloaded functions). It would be harder
> in PHP, but it could be done.
>
>> In your example above the problem is if you need to do more init work on the data you
>> need an extra method call. With the implemented solution you just have to know that
>> the constructor is called after setting the vars, and you can detect it, testing the
>> unique key or so, but need not do so if you don't care.
>>
>>> And I guess it would be impossible to do it the other way round (first setting data,
>>> then calling constructor). The setting of the data can be controlled using the magic
>>> __set() method, so there's no need for __pdoconstruct(), if I understand you
>>> correctly.
>>
>> Are you aware of the fact that __set() is not called for defined variables? Test:
>> <?php
>> class Upset {
>> public $var1;
>> function __set($n, $v) {
>> echo "setting variable $n to: $v\n";
>> $this->$n = $v;
>> }
>> }
>> $c = new Upset();
>> $c->var1 = 'Try this';
>> $c->another = ' and this ';
>> echo "Values are now $c->var1 $c->another\n";
>> ------------------- Result: ----
>> setting variable another to: and this
>> Values are now Try this and this
>>
>>
>
> That is correct - you are directly setting a public variable. Now make $var1 private
> and see what happens.

Let's see, this gives a good reference:

<?php
class Upset {
public $pubvar;
private $privvar;
function __set($n, $v) {
echo "setting variable $n to: $v\n";
$this->$n = $v;
}
function __get($n) {
echo "getting variable $n\n";
if (isset($this->$n)) return $this->$n;
else return null;
}
}
$c = new Upset();
$c->pubvar = 'Try this';
$c->privvar = ' private ';
$c->adhoc = ' and this ';
echo "Values are now $c->pubvar $c->privvar $c->adhoc\n";
------------------- Result is: ----
setting variable privvar to: private
setting variable adhoc to: and this
getting variable privvar
Values are now Try this private and this


/Str.
Re: out of sheer curiosity... [message #177632 is a reply to message #177625] Wed, 11 April 2012 20:10 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jerry Stuckle schrieb:

> No, because the database objects themselves will rely on external
> resources which are not serialized. You have the same problem as before.

The external resource would be the actual database connection here.
Which the database object can easily re-acquire in its __wakeup()
method, like

class MyDatabase
{
public function __wakeup()
{
$this->pdo = new PDO( ... );
}
}

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: out of sheer curiosity... [message #177633 is a reply to message #177624] Wed, 11 April 2012 20:17 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jerry Stuckle schrieb:

>> MyDatabaseSingleton::getInstance() ?
>
> What if you don't want a singleton? Many times I've had the need to
> access different databases, for instance. You are limiting the
> versatility of the class.

MyDatabase::getConnection( $id )

> By definition you can pass arguments to the constructor. That's why
> unserialize() is not a good implementation.

But how would you pass any constructor arguments to an unserialize()
function anyway? You cannot be sure what the string to be unserialized
really contains, so how would you know which constructor arguments to
pass? This could be a job for __set_state(): unserialize() then wouldn't
create objects, but simply call the __set_state() method on the class in
question, passing the unserialized state information and leave it to
that method to reconstruct the actual object. But this does not seem to
be the way PHP works.

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: out of sheer curiosity... [message #177635 is a reply to message #177633] Wed, 11 April 2012 20:30 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 4/11/2012 4:17 PM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
>>> MyDatabaseSingleton::getInstance() ?
>>
>> What if you don't want a singleton? Many times I've had the need to
>> access different databases, for instance. You are limiting the
>> versatility of the class.
>
> MyDatabase::getConnection( $id )
>

Which once again doesn't reuse an existing connection, nor does it
specify what connection is being used. Which host? Which database?

If it's defined within the MyDatabase class, you're restricted to that
one connection/database. If it's defined in the serialized class,
you've limited the usefulness of that class.

All is resolved by passing a database object in the constructor of the
class. You are using the object the program wants - not one predefined
by the class itself.

>> By definition you can pass arguments to the constructor. That's why
>> unserialize() is not a good implementation.
>
> But how would you pass any constructor arguments to an unserialize()
> function anyway? You cannot be sure what the string to be unserialized
> really contains, so how would you know which constructor arguments to
> pass? This could be a job for __set_state(): unserialize() then wouldn't
> create objects, but simply call the __set_state() method on the class in
> question, passing the unserialized state information and leave it to
> that method to reconstruct the actual object. But this does not seem to
> be the way PHP works.
>
> Greetings,
> Thomas
>

Which is a big problem with unserialize(). Other languages handle it
quite well by having different constructors available. For instance,
there could be a constructor which takes the serialized object and an
array (or variable arg list) which would unserialize the data and use
the additional arguments.

But problems like this make almost any but the simplest objects useless
for any type of serialization.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: out of sheer curiosity... [message #177636 is a reply to message #177632] Wed, 11 April 2012 20:31 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 4/11/2012 4:10 PM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
>> No, because the database objects themselves will rely on external
>> resources which are not serialized. You have the same problem as before.
>
> The external resource would be the actual database connection here.
> Which the database object can easily re-acquire in its __wakeup()
> method, like
>
> class MyDatabase
> {
> public function __wakeup()
> {
> $this->pdo = new PDO( ... );
> }
> }
>
> Greetings,
> Thomas
>

Which connection? Which database? Specifying the data here makes the
class less reusable.

And what if you want to use an existing PDO object?

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: out of sheer curiosity... [message #177637 is a reply to message #177636] Wed, 11 April 2012 20:40 Go to previous messageGo to next message
Thomas Mlynarczyk is currently offline  Thomas Mlynarczyk
Messages: 131
Registered: September 2010
Karma: 0
Senior Member
Jerry Stuckle schrieb:

>> class MyDatabase
>> {
>> public function __wakeup()
>> {
>> $this->pdo = new PDO( ... );
>> }
>> }
>
> Which connection? Which database? Specifying the data here makes the
> class less reusable.

The connection parameters would be taken from some config file or they
would have been serialized along with the object.

> And what if you want to use an existing PDO object?

MyDatabaseFactory::getConnectionObject( $config )

Greetings,
Thomas

--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
Re: out of sheer curiosity... [message #177643 is a reply to message #177637] Thu, 12 April 2012 04:02 Go to previous messageGo to next message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 4/11/2012 4:40 PM, Thomas Mlynarczyk wrote:
> Jerry Stuckle schrieb:
>
>>> class MyDatabase
>>> {
>>> public function __wakeup()
>>> {
>>> $this->pdo = new PDO( ... );
>>> }
>>> }
>>
>> Which connection? Which database? Specifying the data here makes the
>> class less reusable.
>
> The connection parameters would be taken from some config file or they
> would have been serialized along with the object.
>

OK, that part would work.

>> And what if you want to use an existing PDO object?
>
> MyDatabaseFactory::getConnectionObject( $config )
>
> Greetings,
> Thomas
>

You have 5 different connections to the database. Which one is the
correct one to use?

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Re: out of sheer curiosity... [message #177649 is a reply to message #177643] Thu, 12 April 2012 10:00 Go to previous messageGo to next message
M. Strobel is currently offline  M. Strobel
Messages: 386
Registered: December 2011
Karma: 0
Senior Member
Am 12.04.2012 06:02, schrieb Jerry Stuckle:
> On 4/11/2012 4:40 PM, Thomas Mlynarczyk wrote:
>> Jerry Stuckle schrieb:
>>
>>>> class MyDatabase
>>>> {
>>>> public function __wakeup()
>>>> {
>>>> $this->pdo = new PDO( ... );
>>>> }
>>>> }
>>>
>>> Which connection? Which database? Specifying the data here makes the
>>> class less reusable.
>>
>> The connection parameters would be taken from some config file or they
>> would have been serialized along with the object.
>>
>
> OK, that part would work.
>
>>> And what if you want to use an existing PDO object?
>>
>> MyDatabaseFactory::getConnectionObject( $config )
>>
>> Greetings,
>> Thomas
>>
>
> You have 5 different connections to the database. Which one is the correct one to use?
>

Follow the same logic you used in the first place.

Anyway, I vote for a streamlined init code executed at every HTTP request, this
matches the nature of the HTTP protocol. I can't see why server name and protocol,
client IP and some session flags would not do it.

For the biggest requirements an application server would be a match.

/Str.
Re: out of sheer curiosity... [message #177651 is a reply to message #177649] Thu, 12 April 2012 11:45 Go to previous message
Jerry Stuckle is currently offline  Jerry Stuckle
Messages: 2598
Registered: September 2010
Karma: 0
Senior Member
On 4/12/2012 6:00 AM, M. Strobel wrote:
> Am 12.04.2012 06:02, schrieb Jerry Stuckle:
>> On 4/11/2012 4:40 PM, Thomas Mlynarczyk wrote:
>>> Jerry Stuckle schrieb:
>>>
>>>> > class MyDatabase
>>>> > {
>>>> > public function __wakeup()
>>>> > {
>>>> > $this->pdo = new PDO( ... );
>>>> > }
>>>> > }
>>>>
>>>> Which connection? Which database? Specifying the data here makes the
>>>> class less reusable.
>>>
>>> The connection parameters would be taken from some config file or they
>>> would have been serialized along with the object.
>>>
>>
>> OK, that part would work.
>>
>>>> And what if you want to use an existing PDO object?
>>>
>>> MyDatabaseFactory::getConnectionObject( $config )
>>>
>>> Greetings,
>>> Thomas
>>>
>>
>> You have 5 different connections to the database. Which one is the correct one to use?
>>
>
> Follow the same logic you used in the first place.
>

And how do you do that? In the first place you pass the database object
you wish to use in the constructor.

> Anyway, I vote for a streamlined init code executed at every HTTP request, this
> matches the nature of the HTTP protocol. I can't see why server name and protocol,
> client IP and some session flags would not do it.
>

What do those have to do with it? Database connection doesn't depend on
the client IP, for instance.

> For the biggest requirements an application server would be a match.
>
> /Str.

And how would that help?

These things are quite easy in true OO languages - and quite often done
when doing transactional programming (like web pages are). But they
can't be done the way PHP implements it.

Just another case of how PHP screws things up.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex(at)attglobal(dot)net
==================
Pages (3): [ «    1  2  3]  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: 5.4 windows installer.
Next Topic: Does PHP5 treat $_SERVER['PHP_AUTH_USER']) differently?
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Wed Dec 11 23:38:36 GMT 2024

Total time taken to generate the page: 0.02738 seconds