Jump to content

Learning oop php


Miko

Recommended Posts

Hello,

 

I'm digging further into php with oop :)

I'm a bit playing with it to get a hand on it and for the moment I'm getting a hand on it :)

 

I've created an object with a function that gets some data from a database, for the test i've created a little db name testusers with a table users, entered some users in (friends that I know) and I want to create a loop to get the data from that db:

 

my code:

 

	 	class person{

 		public function set_name($fname){

 			$sql = "SELECT * FROM users";
 			$query = mysql_query($sql);

 			while($row = mysql_fetch_array($query)){

	 			return $this->fname=$row['fname'];

 			}

 		}

 	}

 

then I have a seperated index.php file:

 

<?php


require_once("functions.php");

?>

<html>
<head>
	<title>Test Functions</title>
</head>
<body>

<?php

	$fname = new person();
	$fname->set_name($fname);

	echo $fname->set_name($fname);

?>

</body>
</html>

 

so I have 2 users in my db, but seems that I get only the first entry of the database.

I'm missing here something I think?

Link to comment
Share on other sites

<?php

//Usually, class names start with an Upper case letter
class Person{
      
  //an array of names set to private
  //meaning you can only access it via the person object
  //set to protected if you want to allow a subclass to access it
  private $names = array();
  
  //function set_name - no need for public indentifier in my opinion - unless its private or protected    
  //why are you bringing in $fname, why are you using it when you sql query seems to be just selecting everyone?
  //and why is it called set_name when you seem to be getting names?    
  function set_name($fname){

	 $sql = "SELECT * FROM users";
	 $query = mysql_query($sql);

	 while($row = mysql_fetch_array($query)){

		//push names onto names array
		array_push($this->names,$row['fname'];

	 }

	 //return array of names
	 return $this->names;

  }
                              
}
?>

Link to comment
Share on other sites

hi, thanks for your answer!

 

the reason that I was bringing in $fname was that I wanted to test out something.

 

But now I'm confused with the $names variable.

I'm stuck with the echo that is in my index.php.

 

return $this->names; 

 

here it should return the var names with values from my loop, correct?

 

in my index.php I have this to echo out the var:

 

<body>

<?php

	$names = new Person();
	$names->set_name();

	echo $names->set_name();

?>

</body>

 

my functions.php

 

class Person{

 		private $names = array();

 		function set_name(){

 			$sql = "SELECT * FROM users";
 			$query = mysql_query($sql);

 			while($row = mysql_fetch_array($query)){

	 			array_push($this->names,$row['fname']);

 			}

 			return $this->names;

 		}

 	}

 

But it prints out 'Array' and that's it.

What am I still doing wrong?

Link to comment
Share on other sites

<body>

   <?php
      
      $names = new Person();
      $names->set_name();
      
      $names_array = $names->set_name();
      
      //loop through
      foreach($names_array as $n){
              echo $n;
      }
         
   ?>

</body>

 

Or you could create a function inside Person that prints them out automatically.

Link to comment
Share on other sites

ok this is very helpfull :)

 

now I've got something funny  ::)

 

So the fields are printed out as I wanted but in double  :P

this offcourse because there is a while loop in my function set_name (in file functions.php) and a foreach loop in my index.php.

The goal is to keep the functions and views seperated.

tried to perform it without a while loop in my function, but didn't work :(

Link to comment
Share on other sites

index.php:

 

<?php

require_once("functions.php");

?>

<html>
<head>
	<title>Test Functions</title>
</head>
<body>

<?php

	$names = new Person();
	$names->get_name();
	$names_array = $names->get_name();

?>

	<table>
		<tr>
			<?php foreach($names_array as $x){ echo "<td>".$x."</td>"; } ?>
		</tr>
	</table>

</body>
</html>

 

functions.php:

 

<?php

 	require_once("config.php");

 	class Person{

 		private $names = array();

 		function get_name(){

 			$sql = "SELECT * FROM users";
 			$query = mysql_query($sql);

 			while($row = mysql_fetch_array($query)){

	 			array_push($this->names,$row['fname']);

 			}

 			return $this->names;

 		}

 	}

?>

Link to comment
Share on other sites

You sort of want to separate this logic out a little bit:

 

You want a simple class for Person, which represents and individual (not a collection of people).

 

We'll start by defining an interface for a Person to conform to.

<?php
interface iPerson {
  public function setName($name);
  public function getName();
}
?>

Then we'll define a solid object of "Person" whom implements the interface for iPerson

<?php
class Person implements iPerson {
  private $_name;
  public function setName($name) { $this->_name = $name; }
  public function getName() { return $this->_name; }
}
?>

 

Then we'll define a collection of Persons, this implements the iPerson interface also to make sure it has the same methods and can be used just like a individual Person.

<?php
class People implements iPerson {
  private $_persons = array();
  public function addPerson(Person $person){ $this->_persons[] = $person; }
  public function setName($name) { throw new Exception("You can't set 'name' for People"); }
  public function getName() { 
    $data = array();
    foreach($this->_persons as $person){
      $data[] = $person->getName();
    }
    return $data;
  }
}
?>

 

Now we also need a DataObject to populate our Person object.

<?php
class PersonDAO {
private $db;
  private $_raw;
  private $_people;
  public function __construct($db){
    $this->db = $db;
  }
  public function load(){
    $sql = "SELECT * FROM users";
    $query = mysql_query($sql, $this->db);
    while($row = mysql_fetch_assoc($query)){
      $this->_raw[$row['id']] = $row;
    }
  }

  public function getPersonById($id){
    if(isset($this->_people[$id])){
      return $this->_people[$id];
    }
    return $this->_people[$id] = $this->getPersonFromRaw($id);
  }

  public function getAllPeople(){
    $people = new People();
    foreach(array_keys($this->_raw) as $id){
      $people->addPerson($this->getPersonById($id));
    }
    return $people;
  }

  private function getPersonFromRaw($id){
    if(isset($this->_raw[$id])){
      $person = new Person();
      $person->setName($this->_raw[$id]['name']);
      return $person;
    }
    return null;
  }
}
?>

 

Now some code to test it all.

<?php

$db = mysql_connect("localhost", "username", "password");
mysql_select_db("databaseName", $db);

$dao = new PersonDAO($db);
$dao->load();
$person = $dao->getPersonById(1);
echo $person->getName();

$people = $dao->getAllPeople();
$names = $people->getName();
foreach($names as $name){
  echo $name;
}
?>

 

Hopefully that will give you a bit of an insight into what is possible.

Link to comment
Share on other sites

thanks for the answer, but I'm just a beginner in oop php.

 

Most of the codes that you have written are still unknown to me.  :confused:

and it is a lot of code for the thing I need o_O.

 

I just wanted to fetch data from my sql db by using a seperate file(functions.php) from my index.php.

Link to comment
Share on other sites

<?php
class People implements iPerson {
  private $_persons = array();
  public function addPerson(Person $person){ $this->_persons[] = $person; }
  public function setName($name) { throw new Exception("You can't set 'name' for People"); }
  public function getName() { 
    $data = array();
    foreach($this->_persons as $person){
      $data[] = $person->getName();
    }
    return $data;
  }
}
?>

 

I'm a bit confused by this why let People implement iPerson if you would throw an exception if they use setName($name) and if you use getName() you'd actually get multiple names. In my opinion People shouldn't even implement iPerson.

Link to comment
Share on other sites

The collection would probably be more meaningful in another context, however I was merely showing that you can use a collection to perform group operations on multiple people. I mangled it slightly so it returns an array, which by definition should invalidate the interface.

 

A better example would be the function "dance()", whereby you could perform dancing for a group of people.

e.g.

 

<?php
interface iPerson {
  // ... previous code implementation
  public function dance();
}
class People implements iPeople {
  // ... previous code implementation
  public function dance(){
    foreach($this->_persons as $person){
      $person->dance();
    }
  }
}
?>

Link to comment
Share on other sites

A better example would be the function "dance()", whereby you could perform dancing for a group of people.

 

Woeps, there goes free will ;)

 

I don't know what the 'interface' even do, same thing with 'implements'

 

I'll try to explain it by example:

 

class Niko {
    public function getFirstname() {
        return $this->_firstName;
    }
}

class Bruno {
    public function getName() {
        return $this->_firstName;
    }
}

 

Both Niko and Bruno are persons however they use both a different method to retrieve their firstname which complicates it for you as a programmer because you would always need to check if an object is an instanceof Bruno or an instanceof Niko.

 

$persons = array(new Niko(), new Bruno());
foreach ($persons as $person) {
   if ($person instanceof Bruno) {
       print $person->getName();
   } else if ($person instanceof Niko) {
       print $person->getFirstname();
   } // What if you had 200 persons? Each implementing their own firstname method?
}

 

To make sure all classes use the same interface (use the same methods) you create an interface.

 

interface IPerson {
    public function getFirstname();
}

class Niko implements IPerson {
    public function getFirstname() {
        $this->_firstName;
    }
}

class Bruno implements IPerson {
    public function getFirstname() {
        $this->_firstName;
    }
}

 

Now you know that if an object implements IPerson it also has the method getFirstname()

 

$persons = array(new Niko(), new Bruno());
foreach ($persons as $person) {
   print $person->getFirstname();
}

 

Now when use an interface and when use an abstract class? You generally use an abstract class when you want to specify default behavior for some methods and leave others to be implemented by the child classes. If you can't provide default behavior for any of the needed methods then you generally use an interface.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.