Page 1 of 1

Returning more than 1 variable inside of a function

Posted: Tue Jan 02, 2007 11:43 am
by impulse()
I have been trying to get into OOP recently and I have come across the problem where I'm writing as many functions as there are variables within a class just to output them to a browser. I've read that function are only able to return 1 variable and there are other ways to do this. At the moment I'm dumping them all into an array and returning the array but it gets confusing unless I'm using an associative array but I don't want to use an associative array due to not being able to create a loop to dump all the values into an associative array. Is there an easier way to do this?

This is my code:

Code: Select all

class People {

  var $name = "Unset";
  var $age = "Unset";
  var $sex = "Unset";

  var $legs = 2;
  var $eyes = 2;
  var $arms = 2;

    public function displayName() {

      return $this->name;

    }

    public function displayAge() {

      return $this->age;

    }

    public function displaySex() {

      return $this->sex;

    }

    public function displayLegs() {

      return $this->legs;

    }

    public function displayEyes() {

      return $this->eyes;

    }

    public function displayArms() {

      return $this->arms;

    }
}

class Ste extends People {

  var $name = "Ste";

  public function steName() {

    return $this->name;

  }
}

# Main Class
$details = new People;
echo "Parent class -  name var: ", $details->displayName(), "\n";

# Extended Class 'Ste'
$steDetails = new Ste;
echo "Ste class - name var: ", $steDetails->steName(), "\n";
I know the code doesn't really have relevance to solving the problem or any use to anything but I thought I best post it due to the name of the forum :)

Posted: Tue Jan 02, 2007 11:58 am
by volka
You might be interested in __get, see http://de3.php.net/manual/en/language.o ... oading.php

Posted: Tue Jan 02, 2007 12:03 pm
by Kieran Huggins
take a look at the GET and SET object methods:
http://www.php.net/manual/en/language.o ... oading.php

They'll save you a little from carpal tunnel syndrome... 8)

@volka: 8O ooooh..... you're fast!

Posted: Tue Jan 02, 2007 12:03 pm
by John Cartwright
or even a normal function, if you don't like magic methods.

Code: Select all

public function getValue($varname)
{
   if (!array_key_exists($varname, $this))
   {
      throw new Exception($varname .' does not exist');
   }
   
    return $this->$varname;
}

$foobar->getValue('username');

Posted: Tue Jan 02, 2007 12:07 pm
by jmut
EDIT: didn't see any of above answers....guess didn't answer quick enough

There seems to be no reason for this extended class.
Here is a snippet that could be more meaningful.

Code: Select all

class People {

  var $name = "Unset";
  var $age = "Unset";
  var $sex = "Unset";

  var $legs = 2;
  var $eyes = 2;
  var $arms = 2;

    public function __construct($name = 'Unset')
    {
     $this->name = $name;
    

     }
      ..........
}

# Main Class
$details = new People();
echo "Parent class -  name var: ", $details->displayName(), "\n";

# Extended Class 'Ste'
$steDetails = new People('Ste');;
echo "Person ste - name var: ", $steDetails->displayName(), "\n";


As for gathering data of each property of an object...it really depends on what you are trying to achive. Several topic might help you with these.
- simple getters....as you do it now
- The Reflection API - could be used to automate this process in samo way.
- Overloading
- Visitor pattern - helps you not to bloat the interface of the object when you try to get context spefic data.... e.g not adding method getNameAndAge() when you already have methods getName() and getAge().

Posted: Tue Jan 02, 2007 12:13 pm
by impulse()
The code wasn't meant to have reason. I was just testing what would be outputted for a variable of the same name, one from a parent class and one from a child class. Once I had found that out I thought there must be a quicker way to output the data. Overloading seems to have the vote at the moment so I'll take a look into it.

Posted: Tue Jan 02, 2007 1:26 pm
by MrPotatoes
Jcart wrote:or even a normal function, if you don't like magic methods.

Code: Select all

public function getValue($varname)
{
   if (!array_key_exists($varname, $this))
   {
      throw new Exception($varname .' does not exist');
   }
   
    return $this->$varname;
}

$foobar->getValue('username');
i've never liked magic functions.

you can always return an array of variables

Posted: Tue Jan 02, 2007 1:39 pm
by RobertGonzalez
Isn't that class in the first post indicative of a registry pattern? Wouldn't that provide a more useful outlet for this?

Posted: Tue Jan 02, 2007 2:05 pm
by John Cartwright
Everah wrote:Isn't that class in the first post indicative of a registry pattern? Wouldn't that provide a more useful outlet for this?
I don't see the connection here. Can you explain?

Posted: Tue Jan 02, 2007 2:59 pm
by RobertGonzalez
Well, taking a page from PatternsforPHP...

Code: Select all

<?php
/**
 * PHP 5 Registry Object
 * 
 * This class is a storehouse for data necessary for the application
 * very similar in style to an application file for .NET apps.
 * 
 * This file will house all needed vars, some defaulted, some set later
 * and can only be accessed by a call to the registry
 */
class Settings
{
	/**
	 * Singleton instantiator
	 *
	 * @var resource
	 */
	private static $_instance = null;
	
	/**
	 * Array that holds all of the settings
	 *
	 * @var array
	 */
	public $settings = array();
	
	/**
	 * Class constructor, this is private
	 *
	 */
	private function __construct()
	{
		// Singelton
	}
	
	/**
	 * Class instantiator
	 *
	 * @return resource
	 */
	public static function get_instance()
	{
		if (self::$_instance === null)
		{
			self::$_instance = new Settings();
		}
		
		return self::$_instance;
	}
	
	/**
	 * Sets a registry setting $label to value $value
	 *
	 * @param string $label
	 * @param mixed $value
	 */
	public function register($label, $value)
    {
    	if (!isset($this->settings[$label]))
    	{
    		$this->settings[$label] = $value;
    	}
    }
    
    /**
     * Clears a registry entry
     *
     * @param string $label
     */
    public function unregister($label)
    {
    	if ( isset($this->settings[$label]) ) 
    	{
    		unset($this->settings[$label]);
    	}
    }
    
    /**
     * Returns a registry entry
     *
     * @param string $label
     * @return mixed
     */
    public function get($label)
    {
    	if ( isset($this->settings[$label]) ) 
    	{
    		return $this->settings[$label];
    	}
    	
    	return false;
    }
    
    /**
     * Returns true if the $label is set, false otherwise
     *
     * @param string $label
     * @return boolean
     */
    public function has($label)
    {
    	return isset($this->settings[$label]);
    }
}
?>
Using this, you could essentially store all application related var/val pairs in the registry using the register() method, then retrieve them using the get() method. Something like...

Code: Select all

<?php
$settings = Settings::get_instance();
$settings->register('george.age', 43);
$settings->register('george.weight', 175);
$settings->register('mary.age', 41);
$settings->register('mary.weight', 120);

// Later on, or in another class, or whatever
echo 'George is ' . $settings->get('george.age');
?>
Or am I totally off in my assessment?

Posted: Tue Jan 02, 2007 3:22 pm
by John Cartwright
I know what a registry is, but I thought we were talking about avoiding getters for every variable?

Posted: Tue Jan 02, 2007 3:31 pm
by volka
I see only one "getter"
public function get($label)

Posted: Tue Jan 02, 2007 5:04 pm
by RobertGonzalez
Jcart wrote:I know what a registry is, but I thought we were talking about avoiding getters for every variable?
I think you are going to need to have access to the vars regardless. The point is that with a registry you now have access to them all with one method as opposed to needing a method for each var.