473,406 Members | 2,769 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,406 software developers and data experts.

inner "nested" classes?

Hello PHP people,

Was wondering if PHP5 had some sort of "nested class" functionality.

I'm trying to figure out how to return an object (with a private
constructor) that has access to variables in another class.

Something like:

$obj = $factory->getObject("1234");

Where getObject() is the ONLY way to get an instance of $obj.

$obj has access to private data from the $factory object.

Kind of like inner and anonymous classes in java I guess.

Any approach to doing this in PHP5?

Jamie
--
http://www.geniegate.com Custom web programming
User Management Solutions Perl / PHP / Java / UNIX

Jul 17 '05 #1
10 12584

"Average_Joe" <jo*@geniegate.com> wrote in message
news:sl****************@pong.tunestar.net...
Hello PHP people,

Was wondering if PHP5 had some sort of "nested class" functionality.

I'm trying to figure out how to return an object (with a private
constructor) that has access to variables in another class.

Something like:

$obj = $factory->getObject("1234");

Where getObject() is the ONLY way to get an instance of $obj.

$obj has access to private data from the $factory object.

Kind of like inner and anonymous classes in java I guess.

Any approach to doing this in PHP5?

Jamie
--
http://www.geniegate.com Custom web programming
User Management Solutions Perl / PHP / Java / UNIX


Don't know if such mechanism thing exists in PHP5. You can always use uniqid
to generate a unique class name, then define the class with eval. If the
name is kept private, then the class is private.

$class = uniqid("Inner");
eval(<<<CLASS

class $class {
}

CLASS
);
Jul 17 '05 #2
Chung Leong wrote:
Don't know if such mechanism thing exists in PHP5. You can always use uniqid
to generate a unique class name, then define the class with eval. If the
name is kept private, then the class is private.

$class = uniqid("Inner");
eval(<<<CLASS

class $class {
}

CLASS
);


That would be not only one of the ugliest hacks I've ever seen, it also
wouldn't be very effective. You can get all declared classes via
http://php.net/get_declared_classes. Security by obscurity by itself
isn't a good idea IMHO.

I've been thinking about this problem a while ago and came to the
conclusion it wasn't possible.

--
Pieter Nobels
Jul 17 '05 #3
Average_Joe wrote:
Something like:

$obj = $factory->getObject("1234");

Where getObject() is the ONLY way to get an instance of $obj.


OK, let's see - I don't have PHP5 handy to test it right now, but try
something like this:

class factory {

function __construct() {
$tr = debug_backtrace();
if($tr[1]['class'] != 'A' || $tr[1]['function'] != 'getObject')
throw new Exception;
}

function getObject() {
self::$instance = new factory;
return(clone(self::$instance));
}
}

$obj = factory::getObject();

Again, this is untested - so I don't know if it will work but may be worth
trying. Since I don't know what the purpose of this is, I can't provide any
more feedback to suggest other methods of accomplishing it.
Jul 17 '05 #4
Zurab Davitiani wrote:
if($tr[1]['class'] != 'A' || $tr[1]['function'] !=

'getObject'

This should read
if($tr[1]['class'] != 'factory' || $tr[1]['function'] != 'getObject'
Jul 17 '05 #5
"Pieter Nobels" <pi******@MOVEpcmania.be> wrote in message
news:_p***********************@phobos.telenet-ops.be...
Chung Leong wrote:
Don't know if such mechanism thing exists in PHP5. You can always use uniqid to generate a unique class name, then define the class with eval. If the
name is kept private, then the class is private.

$class = uniqid("Inner");
eval(<<<CLASS

class $class {
}

CLASS
);


That would be not only one of the ugliest hacks I've ever seen, it also
wouldn't be very effective. You can get all declared classes via
http://php.net/get_declared_classes. Security by obscurity by itself
isn't a good idea IMHO.

I've been thinking about this problem a while ago and came to the
conclusion it wasn't possible.


This is PHP after all. The source code to the class would be available so
it'd be just as easy to remove the "private" keyword in order to access the
private variable. The use of private method/classes has nothing to do with
security so I don't know what you're driving at.
Jul 17 '05 #6
"Zurab Davitiani" <ag*@mindless.com> wrote in message
news:6A**************@newssvr21.news.prodigy.com.. .
Zurab Davitiani wrote:
if($tr[1]['class'] != 'A' || $tr[1]['function'] !=

'getObject'

This should read
if($tr[1]['class'] != 'factory' || $tr[1]['function'] != 'getObject'


Very clever solution. One tiny problem: PHP collapses function names to
lower case, so the comparison should be to 'getobject'.
Jul 17 '05 #7
Chung Leong wrote:
"Zurab Davitiani" <ag*@mindless.com> wrote in message
news:6A**************@newssvr21.news.prodigy.com.. .
Zurab Davitiani wrote:
> if($tr[1]['class'] != 'A' || $tr[1]['function'] !=

'getObject'

This should read
if($tr[1]['class'] != 'factory' || $tr[1]['function'] != 'getObject'


Very clever solution. One tiny problem: PHP collapses function names to
lower case, so the comparison should be to 'getobject'.


That's no longer true for PHP5, unless it's some part of optional PHP4
compatibility mode. PHP5 class and function/method names are in their
proper case.

I finally got around to trying this solution in PHP5, and it worked OK - one
thing missing is a static $instance property definition inside the class. I
still don't get what is the point of this though - maybe developers who
don't read docs - enforce factory class programatically?
Jul 17 '05 #8
In article <rK********************@comcast.com>, Chung Leong wrote:
"Pieter Nobels" <pi******@MOVEpcmania.be> wrote in message
news:_p***********************@phobos.telenet-ops.be...
Chung Leong wrote:
> Don't know if such mechanism thing exists in PHP5. You can always use uniqid > to generate a unique class name, then define the class with eval. If the
> name is kept private, then the class is private.
>
> $class = uniqid("Inner");
> eval(<<<CLASS
>
> class $class {
> }
>
> CLASS
> );
>
>


That would be not only one of the ugliest hacks I've ever seen, it also
wouldn't be very effective. You can get all declared classes via
http://php.net/get_declared_classes. Security by obscurity by itself
isn't a good idea IMHO.

I've been thinking about this problem a while ago and came to the
conclusion it wasn't possible.


This is PHP after all. The source code to the class would be available so
it'd be just as easy to remove the "private" keyword in order to access the
private variable. The use of private method/classes has nothing to do with
security so I don't know what you're driving at.


Seems like no matter how hard we try to squelch the right brain in
programming.. a persons artistic side has to come out. :-)

The idea of random generated class names is artistic to some, but ugly
to others. Thats my theory anyhow. :-)

In *my* case, it wouldn't work, since I need the inner class to have
access to private variables and methods in it's envelope class.

Jamie
--
http://www.geniegate.com Custom web programming
User Management Solutions Perl / PHP / Java / UNIX

Jul 17 '05 #9
In article <fn****************@newssvr27.news.prodigy.com>, Zurab Davitiani wrote:
I finally got around to trying this solution in PHP5, and it worked OK - one
thing missing is a static $instance property definition inside the class. I
still don't get what is the point of this though - maybe developers who
don't read docs - enforce factory class programatically?


Simple example:

Say you've got:

<?php
class Invoice() { .. }

class Item() { ... }

// You want to do:

$item = $invoice->getItem("P100");

echo $item->title();

echo $item->getInvoice()->title(); // get the invoice title.

?>

The idea here is that at no point can anything except Invoice() generate
an instance of Item. (Item has a private constructor)

Furthermore. Say Item is an interface or abstract class, the actual items
are different, but all of them implement an "Item" interface. This way,
you could have a Clothing Item, Electronics Item, etc.. each with
methods specific to the item type. You also can be reasonably assured
that all Item()'s haven't been constructed outside an Invoice().

You know when working with the code that each Item must have a parent
Invoice instance, down the road, if an Item required access to stuff in
the Invoice class (such as a is_sales_tax() method ?) You would be able
to access it, w/out giving access to other areas of the application. (So
that if is_sales_tax() were to change, (lets say sales tax became
dependant on country or something) you would know it was accessed ONLY
in Invoice() and any Item's it generated, making changes easier)

Aside from this, PHP5 is looking really _really_ good. :-)

Jamie
--
http://www.geniegate.com Custom web programming
User Management Solutions Perl / PHP / Java / UNIX

Jul 17 '05 #10
Average_Joe wrote:
Simple example:

Say you've got:

<?php
class Invoice() { .. }

class Item() { ... }

// You want to do:

$item = $invoice->getItem("P100");

echo $item->title();

echo $item->getInvoice()->title(); // get the invoice title.

?>

The idea here is that at no point can anything except Invoice() generate
an instance of Item. (Item has a private constructor)
OK, that's close to how I imagined it as well. In this case, you would make
sure that Item constructor was only called from Invoice class, or throw an
exception. I cannot think of another way to do this other than with
debug_backtrace which is really a workaround (or a hack) for this, not a
language feature.

Since the check would be already done, the Item constructor need not be
private in this case. Indeed if it was, Invoice wouldn't be able to
construct it since the call would come from global namespace.
Furthermore. Say Item is an interface or abstract class, the actual items
are different, but all of them implement an "Item" interface. This way,
you could have a Clothing Item, Electronics Item, etc.. each with
methods specific to the item type. You also can be reasonably assured
that all Item()'s haven't been constructed outside an Invoice().
In order to make sure this works with abstract classes, you would have to
call the parent constructor explicitly. Also, you would have to allow the
parent constructor to complete instantiation - i.e. not throw an exception
- when it's called from a __construct function of a class whose parent
class is "Item". You can use get_parent_class for that.

Also, it's not pretty but every derived class would have to have a similar
check in its constructor. You may create a common method for this in parent
that's inherited by derived classes, but backtrace values would have to
come from constructor function and passed to that method.
You know when working with the code that each Item must have a parent
Invoice instance, down the road, if an Item required access to stuff in
the Invoice class (such as a is_sales_tax() method ?) You would be able
to access it, w/out giving access to other areas of the application. (So
that if is_sales_tax() were to change, (lets say sales tax became
dependant on country or something) you would know it was accessed ONLY
in Invoice() and any Item's it generated, making changes easier)
This is more or less easier to implement. When calling the Item constructor
from Invoice (or through a separate method), pass $this and set it as
Item's parent property; then refer back to it from the Item class by
calling $this->getParent() or $this->parent.
Aside from this, PHP5 is looking really _really_ good. :-)


I would have preferred multiple inheritance to interfaces.
Jul 17 '05 #11

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

Similar topics

10
by: Paul Morrow | last post by:
I'm hoping that someone can explain why I get the following exception. When I execute the code... ###################################### class Parent(object): class Foo(object): baz = 'hello...
3
by: Vinodh Kumar P | last post by:
I abstract a Car, and the parts wihtin a car, with a C++ class. Since only my version of class Car uses the classes defined for its parts, is it a good practice to do like this? class Car {...
5
by: Fabio Rossi | last post by:
Hi! I'm learning C++ from the book "Thinking in C++". Now I'm reading about nested classes and access control. I have written this code #include <iostream> class Outer { private: int...
7
by: Alfonso Morra | last post by:
I have a class that contains a nested class. The outer class is called outer, and the nested class is called inner. When I try to compile the following code, I get a number of errors. It is not...
4
by: Christopher Ireland | last post by:
Hi -- I'm trying to find an example of a nested class implemented within the .NET Framework itself but without much success. I don't suppose that anybody knows of such an example off the top of...
8
by: Etienne Boucher | last post by:
Nested classes are usualy objects made to only live in their parent object instance. In other words... public class Outter { public class Inner { } }
8
by: Robert W. | last post by:
I've almost completed building a Model-View-Controller but have run into a snag. When an event is fired on a form control I want to automatically updated the "connnected" property in the Model. ...
4
by: Sundararajan | last post by:
Dear Folk, I have implemented a nested class as follows: Class Enclosing { string strName; Class Nested1 { }
3
by: Martin Skou | last post by:
I'm experimenting with using Python for a small web interface, using Mark Hammond's nice win32 extensions. I use a small class hierarchy which uses inheritance and nested classes. Here are a...
5
by: Jake K | last post by:
What purpose does nesting a class inside another class typically server? Are there conditions where this would be beneficial? Thanks a lot.
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
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,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.