Dannie,
In the first place, the php language has no inherent support for you to
specify what data you want to keep about an attribute (metadata). Of
couse you can define a class yourself, like your class attrb, but that
class will not magically have instances. Of course you can create
instances yourself, but like all other objects, they only live for the
duration of a request, unless you build some form of persistency. So
basically the answer about 'Config Time' versus 'Run Time' is simple:
there is not something like 'Config Time', objects only exist at runtime.
But OK, we are developers, aren't we? If somthing is not there we can
create it ourselves! You need an object to live longer then one request?
You write a persistency framework. The framework should:
- offer a way to save objects to persistent storage
- offer a way to load objects from persistent storage when needed.
Persistent storage could be a file: you simply serialize the objects to
store them, unserialize them to revive them, using php's built-in
functions. The easiest way is to put all objects into an array, then
serialize the entire array, unserialize it when you need the objects,
then get the object you need from the array. Yes, you need to know the
key of the object in the array. The key of the object (usually called
'id' or 'oid') also answers another question: how do we decide whether
an object that was loaded is the same object as the one we saved? (Of
course it can never be really the same one, but we can treat it as if it
is the same) Two object are thought to be the same if their key is the same.
Of course you can be much more flexible if you store the objects an a
database instead of in a file. Databases allow you to store them
individually, but retrieve lots of them at once, not only by their keys,
but by arbitrary search criteria. You can also store references between
objects by storing foreign keys and use those to retrieve the referred
objects when the references are needed.
Now this does still not make a difference between runtime and config
time. Of course the only difference we really need is a matter of life
cycle: attribute objects are thought to exist for the duration that the
class whose attributes are described is loaded. So if you make an
includeClass function you could first include the class, then create an
object that describes the class (a class descrioptor), then create all
objects that describe the attributes of the class, put them in an array,
put the array in an attribute of the class descriptor, put the class
descriptor in the array that holds all class descriptors. This array
would be in a static or global variable. That will make it survive until
the end of the request, which is as good as it gets.
But do you really need the class descriptors to exist in memory from the
moment the class exists? The alternative is lazy initialization: to load
(or build) a class descriptor dynamicly when someone asks for it, cache
it, and when it is aked for again, return the one from the cache. This
is really a matter of implementation.
You may have noticed that i did not follow your idea of one big array
with attributes. The reason is that in OO design, different classes can
have attributes with the same name, but different specifications. This
is called polymorphism.
You may also have noticed that i did not follow up of your idea of a
class TelephoneNumber extends Attribute{}. The above explains how you
can store metadata in persistent attribute descriptors. You can still
combine that with attribute classes. For the purpose of explanation i
will assume we do not store the attributedescriptors in a database, but
instead create them from code*.
$clsDesc =& getClassDescriptor('Customer');
$att =& new AttributeDescriptor($clsDes, 'phone');
$att->setType('TelephoneNumber');
$att->setMaxLength(10);
$clsDesc->addAttributeDescriptor($att);
As you see the attibute 'phone' is of type 'TelephoneNumber', which is a
class. This is really OO: use objects for everything, then classes can
be used as types. Building the actual objects that are described by
these classDescriptors could be like this:
$myCustomer = new Customer();
$myCustomer->setPhone( new TelephoneNumber ('0518-43834') );
This is very flexible as each attribute type has its own class, but the
disadvantange is you have to make more classes (i.e. more code) and make
more objects (makes your code run slower). This is a classical design
decision: using a type 'text' would be simpeler, but less powerfull. As
allways, it depends on the requirements of your applications.
I guess the same is true for not using metadata but only use attribute
classes: (class TelephoneNumber extends Attribute{} )it is much simpeler
then having metadata, but will obviously be less powerfull. The question
is what kind of power do your applications need? I can't tell the pro's
and con's because i never tried to use only attribute classes. Maybe
someone else can comment on that.
If you want to read more about persistency, attribute descriptors (we
call them propertyDescriptors) you can take a look at:
http://www.phppeanuts.org/site/index...rsistency.html http://www.phppeanuts.org/site/index...escriptor.html
To see how the propertydescriptors etc. are implemented, see
http://www.phppeanuts.org/site/index...meta/meta.html
To see how applications are built with the framework, you can download
the examples and read the tutorial.
Greetings,
Henk Verhoeven,
www.phpPeanuts.org.
* PhpPeanuts does create the Classdescriptors and PropertyDescriptors
from code. It supports layering of the code to create different 'config
times': framework layer, company generic code layer, application layer,
application configuration (install) layer. Normal persistent objects are
stored in/loaded from MySql.
Danimal wrote:
I have been using PHP for a long time... since it was called PHP/FI. I
have a programming design question:
Let say I have this class:
class attrib {
var $lenght;
var $type;
...
}
An attrib is something like:
birthDay
telephoneNumber
address
Each installation of this application will have a different set of
attrib[s] defined. So my question is how do I define create the
attrib[s] because some information is defined at config time and some
is run time. For example:
[Config Time]
telephoneNumber $lenght is 10
[Run Time]
telephoneNumber is 555-555-5000
So I am not sure when at what point I create the object... at config or
at run. because if I create it at config then I only have one instance
of it and depending on the page I may need multiple parent objects to
contain multiple attribs. If I create it at run time then how do I
define its variables like $length.
I know I can accomplish this... it is not a question of how... it is a
question of what is the proper way to do it in OO programming. My tow
thought were that I could extend the class for every attribute like
this:
class telephoneNumber extends attribute{}
And then construct the object... but I would be extending the class
like a hundred different times... is that a problem?
The other way I thought about it was assigning the attrib class a
"name" variable which would hold the type of attrib like
"telephoneNumber". I would then keep a separate array full of attrib
"names" like this:
$attribNames['telephoneNumber'] = array('10','text');
And when I needed to contruct a new attrib I would reference that aray
to get initial values.
Sorry this is long winded I am not sure how to phrase it better.
have a good day,
Dannie