Re: [PHP] Suggestions for class design

2005-09-20 Thread Jochem Maas

Hi Chris,

nice thread, good questions - nice to see some real programming
theory being discussed - does us all some good :-)

here is my take, hth:

Chris W. Parker wrote:

Anas Mughal mailto:[EMAIL PROTECTED]
on Monday, September 19, 2005 4:02 PM said:



The simplest way to solve this problem is as follows:

- Have your Customer class hold only attributes for a customer. This
class would only have getter and setter methods. In the Java world,
this is referred to as a JavaBean.  
- Then, have a DAO class that does your data access functions.


Here is a sample DAO class:


[snip]

Ahh.. I guess this is the same thing that Michael Sims suggested?



class CustomerDAO {


function getCustomer(..) {
...
//return a customer
}



So I return a Customer object that has the set and get methods? And does
that mean I do the following?

-set_first_name()
-set_last_name()
-set_address_1()
-set_address_2()
-set_address_3()
-set_city()
-set_state()


me, I have 'data object' that are subclasses of a 'peer' object, the
'peer' class has all the methods for data handling e.g.

Persistent::submit() (update and insert are handled/determined internally)
Persistent::get()
Persistent::find()
Persistent::findRange()
etc..

the 'data object's have definitions that stipulate 'field'  objects
for each field in the database (usually a 1 to 1 relationship but not
always - for instance there is a VectorField for 1 to many stuff, and an
AssocField for many to many stuff).

if I have a Customer class I can do something _like_:

$cust = Persistent::get('Customer', array('CONTACT_ID' = $id));
$cust-firstname = 'Bob';
$cust-lastname = 'Builder';
$cust-submit();

the 'peer' class has __get() and __set() methods that find the requested
'field' object and return or set its value e.g. (very simplified)

class Persistent
{
function __get($name)
{
if (isset($this-fields[$name])) {
return $this-fields[$name]-getValue();
}

throw new Exception(field '$name' does not exist in this 
(.get_class($this).) object!);
}
}

maybe that gives you an idea about how to avoid constantly writing practically
the same getter/setter methods over and over... and also how to avoid
writing practically identical collection getter functions/methods
(how much different will you getCustomers() method be from your getProducts()
method ... in general anyway ... there are always exceptions to the rule! :)


etc.

Or is there a better way to handle it?



function getCustomers(..) {
...
// return a collection of customers
}



How do I return a collection of customers?



Thanks,
Chris.



--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP] Suggestions for class design

2005-09-20 Thread Chris W. Parker
Sorry I've been so quiet on this topic since I started it but I've
basically been overwhelmed with information! :) I was hoping the
answer(s) would be a lot more plain and simple than it(they) has been so
I could get to implementing some things right away. But I'm afraid it's
going to take me longer than I'd hoped.

It would be great if someone could contribute some more fleshed out and
basic code, but I know we're probably all busy.

As I have spare time I'll go over again (and again) the messages in this
topic as well as Propel and Metastorage.


Thanks,
Chris.

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP] Suggestions for class design

2005-09-19 Thread Jay Blanchard
[snip]
Where I get tripped up is when I realize I'll need to at some point get
more than one customer at a time and thus I want to add a method called
'get_customers()'.
[/snip]

I know that you didn't ask for this, but the point needs discussing given
your assertion above.

Why, at any point, would you need to get more than one customer? One answer
is that all customers or a group of customers will need to be updated/edited
with the same information. Therefore you need a seperate class for multiple
customers which could then be extended by group. A group of customers is a
seperate object. Make sense?

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP] Suggestions for class design

2005-09-19 Thread Chris W. Parker
Jay Blanchard mailto:[EMAIL PROTECTED]
on Monday, September 19, 2005 10:40 AM said:

 [snip]
 Where I get tripped up is when I realize I'll need to at some point
 get more than one customer at a time and thus I want to add a method
 called 'get_customers()'.
 [/snip]

 Why, at any point, would you need to get more than one customer?

Good question.

When I need more than one customer is when I'm displaying them all on an
administration page. Maybe a better example class would be Products. One
individual product is displayed on the product's detail page, but in the
search results I'd normally be using the same Product class to display
all the results which forces me to create a 'get_products()' method.

 One
 answer is that all customers or a group of customers will need to be
 updated/edited with the same information. Therefore you need a
 seperate class for multiple customers which could then be extended by
 group. A group of customers is a seperate object. Make sense?

Well, yes I think it does, but what I'm missing is how this new object
interacts with the original one if it does at all. And what would I call
it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :)

Do I extend the Customer class or is it a stand alone class?



Thanks,
Chris.

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP] Suggestions for class design

2005-09-19 Thread Jay Blanchard
[snip]
Well, yes I think it does, but what I'm missing is how this new object
interacts with the original one if it does at all. And what would I call
it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :)

Do I extend the Customer class or is it a stand alone class?
[/snip]

I think that it should be a stand alone class. The Customers class could
instantiate the needed number of Customer objects and the methods of the
Customers class could affect each Customer object.

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Suggestions for class design

2005-09-19 Thread Mikey

Jay Blanchard wrote:


[snip]
Well, yes I think it does, but what I'm missing is how this new object
interacts with the original one if it does at all. And what would I call
it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :)

Do I extend the Customer class or is it a stand alone class?
[/snip]

I think that it should be a stand alone class. The Customers class could
instantiate the needed number of Customer objects and the methods of the
Customers class could affect each Customer object.

 

+1 for this idea, it is a method I have used on countless projects and 
works very well.


Mikey

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP] Suggestions for class design

2005-09-19 Thread Chris W. Parker
Jay Blanchard mailto:[EMAIL PROTECTED]
on Monday, September 19, 2005 10:53 AM said:

 I think that it should be a stand alone class. The Customers class
 could instantiate the needed number of Customer objects and the
 methods of the Customers class could affect each Customer object.

I'm stuck on how I convert 'SELECT id, name FROM customers WHERE id 
nn' into the needed number of Customer objects.

Here's an attempt:

class Customers
{
var $customers = array();

function get_customers($sql)
{
// instantiate db object
$db = new DB::singleton();

// get results of $sql
$results = $db-execute($sql);

foreach($results as $v)
{
// instantiate one Customer object
$tmp = new Customer;

// populate it with data
$tmp-id   = $v['id'];
$tmp-name = $v['name'];

// store it in array
$this-customers[] = $tmp;
}
}

function delete_customers()
{
// loop through array of customer objects ...
foreach($this-customers as $customer_obj)
{
// ... deleting each customer one at a time
$customer_obj-delete_customer();
}
}
}



Thanks,
Chris.

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Suggestions for class design

2005-09-19 Thread Robert Cummings
On Mon, 2005-09-19 at 14:00, Mikey wrote:
 Jay Blanchard wrote:
 
 [snip]
 Well, yes I think it does, but what I'm missing is how this new object
 interacts with the original one if it does at all. And what would I call
 it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :)
 
 Do I extend the Customer class or is it a stand alone class?
 [/snip]
 
 I think that it should be a stand alone class. The Customers class could
 instantiate the needed number of Customer objects and the methods of the
 Customers class could affect each Customer object.
 
   
 
 +1 for this idea, it is a method I have used on countless projects and 
 works very well.
 
 Mikey
-- 
..
| InterJinn Application Framework - http://www.interjinn.com |
::
| An application and templating framework for PHP. Boasting  |
| a powerful, scalable system for accessing system services  |
| such as forms, properties, sessions, and caches. InterJinn |
| also provides an extremely flexible architecture for   |
| creating re-usable components quickly and easily.  |
`'

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Suggestions for class design

2005-09-19 Thread Rory McKinley
Chris W. Parker wrote:
snip


 class Customer
 {
  var $id;
  var $name;

snip
snip

  function get_customer()
  {

snip
snip


$this-name = $customer['name'];

  }

snip

 Where I get tripped up is when I realize I'll need to at some point get
 more than one customer at a time and thus I want to add a method called
 'get_customers()'.

snip

Hi Chris

Assuming that you have some procedural code, could you not create an
array of Customer objects?
I am not sure what argument would be passed to the get_customer function
as you do not have an argument in the function definition, but if it was
perhaps the customer name, you coud have something like :

/*Procedural code*/

$get_customer_names = 'SELECT ... FROM  WHERE customer ADDRESS LIKE
';

$customer_name_result_set = $db_connection-query($get_customer_names);

for($i=0; $i  $customer_name_result_set-num_rows; $i++) {

$customer_name_result_record = $customer_name_result_set-fetch_row();

$customers[$i] = new Customer;
$customers[$i]-get_customer($customer_name_result_record[0]);


}

That's how I would do it, at any rate (which is probably no
recommendation  ;)  ).

Regards

Rory

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP] Suggestions for class design

2005-09-19 Thread Michael Sims
Chris W. Parker wrote:
 Let's take for example a class called 'Customer' that (obviously)
 manipulates customers in the database. Here is a very basic Customer
 class. (Data validation and the like are left out for brevity.)
[snip]
 Where I get tripped up is when I realize I'll need to at some point
 get more than one customer at a time and thus I want to add a method
 called 'get_customers()'.

 Since an object should be a single instance of something (e.g. ONE
 customer) how do I justify adding the method 'get_customers()'? Or
 better yer, how do I properly add a method like that? (A method where
 instead of using a SQL statement to return ONE customer's data I
 instead return a record set with more than one customer.)
[snip]

Basically you're implementing DAO's (Data Access Objects), similar to what an 
ORM
(Object Relational Mapper) tool would do for you.  There are lots of different
approaches for implementing DAO's, but personally I prefer to use a DAO class 
that
represents one entity in my database (in your example, the Customer), and then 
have
another separate class which is responsible for data operations on my DAO (the 
peer
class).  (This is the approach that many existing ORM tools use, both in the 
PHP and
Java worlds.)  In other words, Customer is only used to access the data that has
been retrieved, but Customer itself doesn't have any methods for retrieving,
updating, deleting, or saving.  The CustomerPeer class handles all the data
operations on Customer.  If you want a particular Customer instance, you ask the
peer to retrieve it for you, and it returns the appropriate object.  If you 
want to
save changes to a Customer, you retrieve the right instance, set its attributes,
then give it back to the peer class which handles the database interaction.  
So, the
Customer class is completely ignorant of the database, and is only concerned 
with
giving you access to the data that is related to that Customer (and any other 
app
specific methods that it makes since for the Customer class to handle).

The advantage to using this approach is that you can easily have your peer class
return an array of Customer objects, each one representing only one customer.

Chris W. Parker wrote:
 Well, yes I think it does, but what I'm missing is how this new object
 interacts with the original one if it does at all. And what would I
 call it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :)

 Do I extend the Customer class or is it a stand alone class?

As stated, I wouldn't recommend creating a new class to hold the Customers.  
Just
use a normal PHP array of Customer objects.

In your spare time, take a look at Propel (http://propel.phpdb.org/), an ORM for
PHP5.  I wouldn't suggest trying to introduce something like this in the middle 
of
an existing project, but consider toying around with it for a future project.  I
used this for my last application with great success.  It used 20 DAO's, 
similar to
your Customer object, and Propel saved me a lot of tedious work in implementing 
all
of the data-related methods+getters/setters for these 20 objects.  If you have 
any
questions about it feel free to drop me a line or check out the Propel mailing 
list
which is very helpful.

HTH...

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP] Suggestions for class design

2005-09-19 Thread Chris W. Parker
Michael Sims mailto:[EMAIL PROTECTED]
on Monday, September 19, 2005 12:04 PM said:

 Basically you're implementing DAO's (Data Access Objects), similar to
 what an ORM (Object Relational Mapper) tool would do for you.
[snip]

Thanks for the info, and I'll check out the Propel site a little later,
but this is basically what I was saying I don't understand.

I'd appreciate some actual code recommendations as I have a hard time
understanding the abstract descriptions of how objects should work and
be designed.



Chris.

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Suggestions for class design

2005-09-19 Thread Satyam

Chris W. Parker [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]
Jay Blanchard mailto:[EMAIL PROTECTED]
on Monday, September 19, 2005 10:40 AM said:

 [snip]
 Where I get tripped up is when I realize I'll need to at some point
 get more than one customer at a time and thus I want to add a method
 called 'get_customers()'.
 [/snip]

 Why, at any point, would you need to get more than one customer?

Good question.

When I need more than one customer is when I'm displaying them all on an
administration page. Maybe a better example class would be Products. One
individual product is displayed on the product's detail page, but in the
search results I'd normally be using the same Product class to display
all the results which forces me to create a 'get_products()' method.

---

The  signs don't seem to show up on this reply, sorry.

Anyway, I have often found the need to make an object and a collection of 
the same kind of objects.  A Customers class containing Customer items, 
Products and Product.   Usually, the collections all look quite the same, 
they have the Add (which gives me a brand new initialized item object) , 
Find (which returns another instance of the Customers class, this with a 
subset of the whole collection), Get (returns and individual item based on a 
key), Delete (you cannot ask an object to delete itself while you are having 
a reference to it), Update (call the Update method of the modified items), 
then, if the language allows, a means to iterate over it and posibly some 
sort alternatives.

Beware, though, that this sounds nice and proper except when the collection 
starts loading and taking up memory.   Then you can handle several 
strategies, the first is 'load as you go' or 'on demand'.   If nobody asks 
for it, don't load it.   Then, you can load the properties on demand as 
well.  You might only load the primary keys first, to be able to enumerate 
them and then load the rest of the properties when the get_() function 
is called.  Actually, from an SQL standpoint, it is better to subdivide your 
fields into those which are used most often, and have them loaded  as a 
group, then several sets of specific fields, groups that usually go together 
(like an address record, if the street is accessed, there is a good change 
that the zip will also be accessed, so, load them both when either one is 
read.  Several internal flags should keep track of which set of fields are 
loaded for each set.

Sounds terrible?   Yes, it is.  It is much faster to rely on the SQL server 
to handle most of the job of these collections.   If you are just 
sequentially fetching records to show on a listing, it is easier to let them 
come from the database, a record at a time, and send it right to the client, 
using and reusing the memory of the resultset over and over.  Much faster 
than loading them in either an array or a collection and then showing them 
from there.   Specially if using them in an environment like a web server 
where the connection is not persistent and whatever gets loaded in response 
to a page request gets lost after that is handled.  They are much more 
usefull in batch processes, where you can hold of to that information for 
quite a while, and it is worth to have it handy.  But we don't do that kind 
of processes any longer these days.

Satyam



 One
 answer is that all customers or a group of customers will need to be
 updated/edited with the same information. Therefore you need a
 seperate class for multiple customers which could then be extended by
 group. A group of customers is a seperate object. Make sense?

Well, yes I think it does, but what I'm missing is how this new object
interacts with the original one if it does at all. And what would I call
it? 'Multiple_Customers'? Or.. perhaps just 'Customers'! :)

Do I extend the Customer class or is it a stand alone class?



Thanks,
Chris. 

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Suggestions for class design

2005-09-19 Thread M Saleh EG
From what I understand is you need a data objects class. Use a generic class 
such as PEAR's DB_DataObject (http://pear.php.net/package/DB_DataObject).

All you have to do is give the table name and the class for example would be 
in our case
DB_DataObject_Customer

And then querying the table would be in a line such as 
[code]
$customer_data=new DB_DataObject_Customer();
$customer-get, -insert,-find, -update and the other goodies given that 
you supply the right parameters.
[/code]

HTH.


Re: [PHP] Suggestions for class design

2005-09-19 Thread Anas Mughal
The simplest way to solve this problem is as follows:

- Have your Customer class hold only attributes for a customer. This class 
would only have getter and setter methods. In the Java world, this is 
referred to as a JavaBean.
- Then, have a DAO class that does your data access functions.

Here is a sample DAO class:


class CustomerDAO {

function getCustomer(..) {
...
//return a customer
}

function getCustomers(..) {
...
// return a collection of customers
}

function saveCustomer(..) {
...
}
 
}


Hope this helps.
--
Anas Mughal



On 9/19/05, Chris W. Parker [EMAIL PROTECTED] wrote:
 
 Hello,
 
 Every time I write some classes I always come across the same
 fundamental problem that I haven't figured out how to solve/approach
 yet. I'm not exactly sure how to put it into words simply but here
 goes...
 
 Let's take for example a class called 'Customer' that (obviously)
 manipulates customers in the database. Here is a very basic Customer
 class. (Data validation and the like are left out for brevity.)
 
 class Customer
 {
 var $id;
 var $name;
 
 function add_customer()
 {
 // create sql statement
 $sql = INSERT INTO ...;
 
 // create db connection
 $db = DB::singleton();
 
 // execute SQL
 $db-execute($sql);
 }
 
 function delete_customer()
 {
 // create sql statement
 $sql = DELETE FROM ...;
 
 // create db connection
 $db = DB::singleton();
 
 // execute SQL
 $db-execute($sql);
 }
 
 function get_customer()
 {
 // create sql statement
 $sql = SELECT ... FROM ...;
 
 // create db connection
 $db = DB::singleton();
 
 // execute SQL
 $customer = $db-execute($sql);
 
 // populate object variables
 $this-id = $customer['id'];
 $this-name = $customer['name'];
 }
 }
 
 (Unless I've already got some major design flaws I think we should be
 good to go.)
 
 Where I get tripped up is when I realize I'll need to at some point get
 more than one customer at a time and thus I want to add a method called
 'get_customers()'.
 
 Since an object should be a single instance of something (e.g. ONE
 customer) how do I justify adding the method 'get_customers()'? Or
 better yer, how do I properly add a method like that? (A method where
 instead of using a SQL statement to return ONE customer's data I instead
 return a record set with more than one customer.)
 
 The class in its current state can't handle data like that so I have to
 then rethink the design and a new object variable called $customers
 where I store the record set that is in return accessed directly by the
 calling page itself.
 
 With the way I'm working with these objects now they seem less like
 objects and more like an organized collection of functions.
 
 
 I'd appreciate some actual code recommendations as I have a hard time
 understanding the abstract descriptions of how objects should work and
 be designed.
 
 
 
 Thanks,
 Chris.
 
 Thanks!
 Chris.
 
 --
 PHP General Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php
 
 


-- 
Anas Mughal