/    Sign up×
Community /Pin to ProfileBookmark

A Project to Understand Classes and Methods

So I set up a project for myself to understand Classes and Method, that, if
people are willing to help, I think would really help me understand exactly
what is going on under the hood. I use functions regularly, as with PHP in
general. This though is something new to me and I believe will help me
expand my knowledge immensely! Here is what I am doing and what I am
starting from.

[code]
1. Create a collection of 10 fictional full names (last, and first) and give them ids (this could be an index)
[/code]

[code=php]
/* from fictional_characters.php */

$fChars = array(
array(
‘uid’ => 0,
‘from’ => ‘Comic Book Guy on The Simpsons’,
‘name’ => ‘Jeff Albertson’,
),
array(
‘uid’ => 1,
‘from’ => ‘Barbies real name’,
‘name’ => ‘Barbara Roberts’,
),
array(
‘uid’ => 2,
‘from’ => ‘Sesame Street Mammoth’,
‘name’ => ‘Aloysius Snuffleupagus’,
),
array(
‘uid’ => 3,
‘from’ => ‘Peanuts Peppermint Patty’,
‘name’ => ‘Patricia Reichardt’,
),
array(
‘uid’ => 5,
‘from’ => ‘The Wizard of Oz’,
‘name’ => ‘Oscar Diggs’,
),
array(
‘uid’ => 6,
‘from’ => ‘Mr. Clean’,
‘name’ => ‘Veritably Clean’,
),
array(
‘uid’ => 7,
‘from’ => ‘The Man in the Yellow Hat from Curious George’,
‘name’ => ‘Ted Shackleford’,
),
array(
‘uid’ => 8,
‘from’ => ‘Monopoly mascot Rich Uncle Pennybags’,
‘name’ => ‘Milburn Pennybags’,
),
array(
‘uid’ => 9,
‘from’ => ‘The Skipper from Gilligans Island’,
‘name’ => ‘Jonas Grumby’,
),
array(
‘uid’ => 10,
‘from’ => ‘Shaggy from Scooby Doo’,
‘name’ => ‘Norville Rogers’,
),

);
[/code]

This first part is easy and something I have done before, so on
to the next one where I start getting confused.

to post a comment
PHP

14 Comments(s)

Copy linkTweet thisAlerts:
@ehimeauthorOct 12.2010 — <i>
</i>2. Create a class called Characters that takes this collection/array as an initialization argument


Now I can create a class, but I'm not sure about the initialization argument part or

what it really means. Here is my attempt at it though.

[code=php]
<?php

include('fictional_characters.php');

class Characters {
function __construct($fChars) { /*****/ }
}

$obj = new Characters($fChars);
print_r($obj); //should return array?

?>
[/code]
Copy linkTweet thisAlerts:
@NogDogOct 12.2010 — [code=php]
class Characters
{
private $characters = array();
public function __construct($characters)
{
$this->characters = $characters;
}
}
[/code]


However, if you truly want to get object-oriented about it, each character could be an object:

[code=php]
<?php

class FictionalCharacter
{
public $uid;
public $name;
public $from;
public function __construct($uid, $name, $from)
{
$this->uid = $uid;
$this->name = $name;
$this->from = $from;
}
}

class FictionalCharacterCollection
{
private $characters = array();
public function __construct($data = array())
{
foreach($data as $character) {
if(isset($character['uid']) && isset($character['name']) &&
isset($character['from'])) {
$this->add(new FictionalCharacter($character['uid'],
$character['name'],
$character['from']));
}
else {
throw new Exception("Invalid array for Fictional Character");
}
}
}
public function add(FictionalCharacter $character)
{
$this->characters[$character->uid] = $character;
}
public function getAll()
{
return $this->character;
}
public function getByUid($uid)
{
return (isset($data[$uid])) ? $data[$uid] : false;
}
}
[/code]
Copy linkTweet thisAlerts:
@ehimeauthorOct 12.2010 — Awesome your actually started to kill a few of my future questions.

Can you explain to me the "what why and how" of what is going on

in your second codeblock?

Oh and btw, I think I'm using this incorrectly

class, call, and array:
[code=php]

<?php

$cc = array(
array(
'uid' => 0,
'from' => 'Comic Book Guy on The Simpsons',
'first' => 'Jeff Albertson',
),
array(
'uid' => 1,
'from' => 'Barbies real name',
'first' => 'Barbara Roberts',
),
array(
'uid' => 2,
'from' => 'Sesame Street Mammoth',
'first' => 'Aloysius Snuffleupagus',
),
array(
'uid' => 3,
'from' => 'Peanuts Peppermint Patty',
'first' => 'Patricia Reichardt',
),
array(
'uid' => 5,
'from' => 'The Wizard of Oz',
'first' => 'Oscar Diggs',
),
);

class FictionalCharacter
{
public $uid;
public $name;
public $from;
public function __construct($uid, $name, $from)
{
$this->uid = $uid;
$this->name = $name;
$this->from = $from;
}
}

class FictionalCharacterCollection
{
private $characters = array();
public function __construct($data = array())
{
foreach($data as $character) {
if(isset($character['uid']) && isset($character['name']) &&
isset($character['from'])) {
$this->add(new FictionalCharacter($character['uid'],
$character['name'],
$character['from']));
}
else {
throw new Exception("Invalid array for Fictional Character");
}
}
}
public function add(FictionalCharacter $character)
{
$this->characters[$character->uid] = $character;
}
public function getAll()
{
return $this->character;
}
public function getByUid($uid)
{
return (isset($data[$uid])) ? $data[$uid] : false;
}
}

$obj = new FictionalCharacter($cc);
echo '<pre>'; print_r($obj); echo '</pre>';

?>
[/code]


returned array:
<i>
</i>Warning: Missing argument 2 for FictionalCharacter::__construct(), called in C:xampplitehtdocslocal_test.php on line 76 and defined in C:xampplitehtdocslocal_test.php on line 37

Warning: Missing argument 3 for FictionalCharacter::__construct(), called in C:xampplitehtdocslocal_test.php on line 76 and defined in C:xampplitehtdocslocal_test.php on line 37

FictionalCharacter Object
(
[uid] =&gt; Array
(
[0] =&gt; Array
(
[uid] =&gt; 0
[from] =&gt; Comic Book Guy on The Simpsons
[first] =&gt; Jeff Albertson
)

<i> </i> [1] =&gt; Array
<i> </i> (
<i> </i> [uid] =&gt; 1
<i> </i> [from] =&gt; Barbies real name
<i> </i> [first] =&gt; Barbara Roberts
<i> </i> )

<i> </i> [2] =&gt; Array
<i> </i> (
<i> </i> [uid] =&gt; 2
<i> </i> [from] =&gt; Sesame Street Mammoth
<i> </i> [first] =&gt; Aloysius Snuffleupagus
<i> </i> )

<i> </i> [3] =&gt; Array
<i> </i> (
<i> </i> [uid] =&gt; 3
<i> </i> [from] =&gt; Peanuts Peppermint Patty
<i> </i> [first] =&gt; Patricia Reichardt
<i> </i> )

<i> </i> [4] =&gt; Array
<i> </i> (
<i> </i> [uid] =&gt; 5
<i> </i> [from] =&gt; The Wizard of Oz
<i> </i> [first] =&gt; Oscar Diggs
<i> </i> )

<i> </i> )

<i> </i>[name] =&gt;
<i> </i>[from] =&gt;
)



My second and third arg's are already in my array though correct?
Copy linkTweet thisAlerts:
@SrWebDeveloperOct 12.2010 — Considering the simplicity of the instructions and the lack of any other functions to manipulate the data, you've done very well. The fact you're a little cloudy as to how the code really works, let me highly summarize this way:

A class is nothing more than a portable set of functions that are object oriented (real world objects translated into code, which brings all variables and functions under one name).

[I]What you did was create a class named "Characters" with its constructor set to take one argument. The constructor syntax you used is for PHP5 and allows the code within the constructor to automatically execute when the class object is initiated including any initialization you might need before that object is used.[/I]

You could have also added a destructor (PHP5) which will be called when the object is removed or explicitly destroyed during a defined shutdown sequence, i.e.

[code=php]function __destruct() {
print "Destructing ".$this->myvariable;
}
[/code]


I suggest you read the first few sections here to learn more about PHP classes and how they work. This reply is extremely novice oriented, OOP can be very complex for the advanced developer, so learn the ground rules and basics first so your foundation is good.

I also suggest informally that the class code itself be the included file, not the code that sets your associative array. To keep things organized create a folder called "classes" or whatever, put all your classes there as individually named files i.e. class_character.php. This also allows you to import third party classes and export your own more easily. Just a thought, to each their own, as always.

-jim
Copy linkTweet thisAlerts:
@SrWebDeveloperOct 12.2010 — Note: The code nogdog added is truly an OOP approach as the class will continue to work just fine so long as the associative array structure (uid, name, from) do not change. Perfect for one application, i.e. yours.

However, simply passing the array as you did works as well, each array element being accessible as $this->fChars so you can iterate through it and pull the keys and values that way. I want to point out that passing the array is the "portable" approach I mentioned earlier, i.e. your class might be used by a third party or a different app where the keys might change. Knowing when to do which depends on what you want the app to do and if you plan on making classes that extend other classes in parent/child relationships via multiple classes that work together. There are many ways to do the same thing, and this entire "flexible" object oriented approach is a major reason why developers favor it for many projects.

Of course nogdog's approach is where you should be heading, intellectually. It exemplifies how objects are enabled, organized and processed via OOP vs. a simple function passing only one array or without a class at all.

-j9im
Copy linkTweet thisAlerts:
@ehimeauthorOct 12.2010 — I'm deff taking your advice Jim, I've just moved everything around

like you recommended, and am reading what you recommend. Code

as of now

[code=php]
<?php

require_once('classes/class_characters.php');

$fc = array(array('uid'=> 0,'from'=> 'Comic Book Guy on The Simpsons','name'=> 'Jeff Albertson',),array('uid' => 1,'from' => 'Barbies real name','name' => 'Barbara Roberts',),array('uid' => 2,'from' => 'Sesame Street Mammoth','name' => 'Aloysius Snuffleupagus',),array('uid' => 3,'from' => 'Peanuts Peppermint Patty','name' => 'Patricia Reichardt',),array('uid' => 5,'from' => 'The Wizard of Oz','name' => 'Oscar Diggs',),array('uid' => 6,'from' => 'Mr. Clean','name' => 'Veritably Clean',),array('uid' => 7,'from' => 'The Man in the Yellow Hat from Curious George','name' => 'Ted Shackleford',),array('uid' => 8,'from' => 'Monopoly mascot Rich Uncle Pennybags','name' => 'Milburn Pennybags',),array('uid' => 9,'from' => 'The Skipper from Gilligans Island','name' => 'Jonas Grumby',),array('uid' => 10,'from' => 'Shaggy from Scooby Doo','name' => 'Norville Rogers',));

$obj = new fictionalCharacters($fc);
print_r($obj);

?>
[/code]


So Jim to understand on what Nog did, could you explain a bit?

Also like I was asking above, I'm a bit confused over the need

of args two and three of the class, since they're already in the

array. If they already exist why would they throw an error?
Copy linkTweet thisAlerts:
@NogDogOct 12.2010 — Just got back from some errands, and noticed a bug in the code I posted earlier. The FictionalCharacterCollection::getByUid() method should be using $this->characters instead of $data. Here's a fixed version, with some sample usage at the end (which I actually tested ? ):
[code=php]
<?php
class FictionalCharacter
{
public $uid;
public $name;
public $from;
public function __construct($uid, $name, $from)
{
$this->uid = $uid;
$this->name = $name;
$this->from = $from;
}
}
class FictionalCharacterCollection
{
private $characters = array();
public function __construct($data = array())
{
foreach($data as $character) {
if (isset($character['uid']) && isset($character['name']) && isset($character['from'])) {
$this->add(new FictionalCharacter($character['uid'], $character['name'], $character['from']));
} else {
throw new Exception("Invalid array for Fictional Character");
}
}
}
public function add(FictionalCharacter $character)
{
$this->characters[$character->uid] = $character;
}
public function getAll()
{
return $this->character;
}
public function getByUid($uid)
{
return (isset($this->characters[$uid])) ? $this->characters[$uid] : false;
}
}
// TEST
$fc = array(
array(
'uid' => 0,
'from' => 'Comic Book Guy on The Simpsons',
'name' => 'Jeff Albertson',
) ,
array(
'uid' => 1,
'from' => 'Barbies real name',
'name' => 'Barbara Roberts',
) ,
array(
'uid' => 2,
'from' => 'Sesame Street Mammoth',
'name' => 'Aloysius Snuffleupagus',
) ,
array(
'uid' => 3,
'from' => 'Peanuts Peppermint Patty',
'name' => 'Patricia Reichardt',
) ,
array(
'uid' => 5,
'from' => 'The Wizard of Oz',
'name' => 'Oscar Diggs',
) ,
array(
'uid' => 6,
'from' => 'Mr. Clean',
'name' => 'Veritably Clean',
) ,
array(
'uid' => 7,
'from' => 'The Man in the Yellow Hat from Curious George',
'name' => 'Ted Shackleford',
) ,
array(
'uid' => 8,
'from' => 'Monopoly mascot Rich Uncle Pennybags',
'name' => 'Milburn Pennybags',
) ,
array(
'uid' => 9,
'from' => 'The Skipper from Gilligans Island',
'name' => 'Jonas Grumby',
) ,
array(
'uid' => 10,
'from' => 'Shaggy from Scooby Doo',
'name' => 'Norville Rogers',
)
);
// instantiate a collection using that array:
$test = new FictionalCharacterCollection($fc);
// show what we now have:
echo "<pre>".print_r($test,1)."</pre>";
// lets grab one character and echo his/her name:
echo $test->getByUid(5)->name; // can chain them since getByUid() returns an object
[/code]
Copy linkTweet thisAlerts:
@NogDogOct 12.2010 — PS: Here is the class definition stuff with full comments to help clarify(?).
[code=php]
<?php
/**
* Defines a fictional character
*/
class FictionalCharacter
{
/**
* @var integer Character ID
*/
public $uid;
/**
* @var string Name of character
*/
public $name;
/**
* @var string Source of character
*/
public $from;
/**
* Constructor
* @return void
* @param int $uid
* @param string $name
* @param string $from
*/
public function __construct($uid, $name, $from)
{
$this->uid = $uid;
$this->name = $name;
$this->from = $from;
}
}
/**
* A collection of fictional character objects
*/
class FictionalCharacterCollection
{
/**
* @var array FictionalCharacter objects
*/
private $characters = array();
/**
* Constructor
* @return void
* @param array $data [optional] each element is array with keys 'uid',
* 'name', and 'from'
*/
public function __construct($data = array())
{
foreach($data as $character) {
if (isset($character['uid']) && isset($character['name']) && isset($character['from'])) {
$this->add(new FictionalCharacter($character['uid'], $character['name'], $character['from']));
} else {
throw new Exception("Invalid array for Fictional Character");
}
}
}
/**
* Add one character to the collection
* @return void
* @param object $character FictionalCharacter
*/
public function add(FictionalCharacter $character)
{
$this->characters[$character->uid] = $character;
}
/**
* Get the entire collection as an array of objects
* @return array
*/
public function getAll()
{
return $this->character;
}
/**
* Get one character by its ID
* @return object FictionalCharacter
* @param int $uid
*/
public function getByUid($uid)
{
return (isset($this->characters[$uid])) ? $this->characters[$uid] : false;
}
}
[/code]

Can you tell I'm bored today? ?
Copy linkTweet thisAlerts:
@SrWebDeveloperOct 12.2010 —  I'm a bit confused over the need

of args two and three of the class, since they're already in the

array.[/quote]


As you asked me, my answer is there isn't any need, it's just a simple demonstrating of [B]how[/B] these variables might be sensibly organized and manipulated via an OOP approach, that's all. But I'll let nogdog work with you since he was gracious enough to post some cool code to demonstrate principles of OOP ..... and clearly has time on his hands! :rolleyes:
Copy linkTweet thisAlerts:
@NogDogOct 12.2010 — As far as the 3 args versus 1 in the FictionalCharacter class's constructor, it was my choice to keep the interface as generic as possible and not assuming that the data source would be an array. You could make it more flexible by using [url=http://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list]variable length argument list[/url], and if one arg is received, then treat it as an array, while if 3 are received, then treat them as the 3 separate scalar attributes (with appropriate validation for each case).

Ultimately, your data might come from a config file in the parse_ini_file() format, or an XML file, or a relational DBMS; so you might need to keep the base classes fairly simple and not locked in to one approach, and then perhaps use something like the Decorator Pattern to wrap them in an appropriate class to deal with a specific data source. (See how easy it is to turn a "simple" exercise into a "complex" one? ? )
Copy linkTweet thisAlerts:
@ehimeauthorOct 12.2010 — So Nog considering it is required now to use a three args

for this function, how do I (we?) keep the errors out? Would

this require me to write something like this
[code=php]
$obj = new fictionalCharacter($fc, null, null); //$fc is the array
print_r($obj);
[/code]

just to handle the class? I noticed that when I call data like so

[code=php]
$obj = new fictionalCharacter(9, 'John Doe', 'A male party whose true identity is unknown or must be withheld for legal reasons.');
print_r($obj);
[/code]


it will return that as an ID'd array, but doesn't seem to handle an entire pre assembled

array like what I'm already using. Am I calling this wrong? And no worries about being out

and about, I just got back from lunch with my daughter. I'm glad the biggest of her problems

so far is trying to figure out base math and the differences between fruits and veggies.

I see this as an issue for a few of my upcoming questions that had to do with classes, such

as a search function, display all in alphabetical, and add/delete users, or append/detach traits

(I just need one example of append/detach, no reason to go crazy). Like I said, this is really a

crash course for me in classes, and I saw those and a few more as some of the biggest things

I might deal with in a real world situation.
Copy linkTweet thisAlerts:
@NogDogOct 12.2010 — Here's a variation using variable arguments. While it adds flexibility, it blurs the constructor's interface, making it a bit more problematic in terms of clarity of use and future maintenance. (My choice would probably to leave it the way I originally had it, requiring the client code to deconstruct any array elements into scalar values when calling this constructor, keeping things clean and allowing the detection of programmer errors at the parser level.)
[code=php]
/**
* Defines a fictional character
*/
class FictionalCharacter
{
/**
* @var integer Character ID
*/
public $uid;
/**
* @var string Name of character
*/
public $name;
/**
* @var string Source of character
*/
public $from;
/**
* Constructor
* @return void
* @param mixed Either $uid, $name, $from OR array
*/
public function __construct()
{
switch(func_num_args()) {
case 3:
$this->uid = func_get_arg(0);
$this->name = func_get_arg(1);
$this->from = func_get_arg(2);
break;
case 1:
list($uid, $name, $from) = func_get_arg(0);
$this->uid = $uid;
$this->name = $name;
$this->from = $from;
default:
throw new Exception("Incorrect number of arguments");
}
}
}
[/code]
Copy linkTweet thisAlerts:
@SrWebDeveloperOct 13.2010 — Or a traditional get/set for each so the sequence isn't important (nor is the constructor, for that matter).
Copy linkTweet thisAlerts:
@NogDogOct 13.2010 — Or a traditional get/set for each so the sequence isn't important (nor is the constructor, for that matter).[/QUOTE]

Or even a not-quite-traditional __get()/__set(). ?
×

Success!

Help @ehime spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 6.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @nearjob,
tipped: article
amount: 1000 SATS,

tipper: @meenaratha,
tipped: article
amount: 1000 SATS,

tipper: @meenaratha,
tipped: article
amount: 1000 SATS,
)...