PHP  
downloads | documentation | faq | getting help | | php.net sites | links 
search for in the  
previousVariable functionsextendsnext
Last updated: Tue, 28 May 2002
view this page in Printer friendly version | English | Brazilian Portuguese | Czech | Dutch | French | German | Hungarian | Italian | Japanese | Korean | Polish | Romanian | Russian | Spanish | Turkish

Luku 13. Classes and Objects

class

A class is a collection of variables and functions working with these variables. A class is defined using the following syntax:

<?php
class Cart
{
    var $items;  // Items in our shopping cart
   
    // Add $num articles of $artnr to the cart
 
    function add_item ($artnr, $num)
    {
        $this->items[$artnr] += $num;
    }
   
    // Take $num articles of $artnr out of the cart
 
    function remove_item ($artnr, $num)
    {
        if ($this->items[$artnr] > $num) {
            $this->items[$artnr] -= $num;
            return true;
        } else {
            return false;
        }   
    }
}
?>

This defines a class named Cart that consists of an associative array of articles in the cart and two functions to add and remove items from this cart.

Varo

The following cautionary notes are valid for PHP 4.

The name stdClass is used interally by Zend and is reserved. You cannot have a class named stdClass in PHP.

The function names __sleep and __wakeup are magical in PHP classes. You cannot have functions with these names in any of your classes unless you want the magic functionality associated with them. See below for more information.

PHP reserves all function names starting with __ as magical. It is recommended that you do not use function names with __ in PHP unless you want some documented magic functionality.

Huomaa: In PHP 4, only constant initializers for var variables are allowed. To initialize variables with non-constant values, you need an initialization function which is called automatically when an object is being constructed from the class. Such a function is called a constructor (see below).

<?php
/* None of these will work in PHP 4. */
class Cart
{
    var $todays_date = date("Y-m-d");
    var $name = $firstname;
    var $owner = 'Fred ' . 'Jones';
    var $items = array("VCR", "TV");
}

/* This is how it should be done. */
class Cart
{
    var $todays_date;
    var $name;
    var $owner;
    var $items;

    function Cart()
    {
        $this->todays_date = date("Y-m-d");
        $this->name = $GLOBALS['firstname'];
        /* etc. . . */
    }
}
?>

Classes are types, that is, they are blueprints for actual variables. You have to create a variable of the desired type with the new operator.

<?php
$cart = new Cart;
$cart->add_item("10", 1);

$another_cart = new Cart;
$another_cart->add_item("0815", 3);

This creates the objects $cart and $another_cart, both of the class Cart. The function add_item() of the $cart object is being called to add 1 item of article number 10 to the $cart. 3 items of article number 0815 are being added to $another_cart.

Both, $cart and $another_cart, have functions add_item(), remove_item() and a variable items. These are distinct functions and variables. You can think of the objects as something similar to directories in a filesystem. In a filesystem you can have two different files README.TXT, as long as they are in different directories. Just like with directories where you'll have to type the full pathname in order to reach each file from the toplevel directory, you have to specify the complete name of the function you want to call: In PHP terms, the toplevel directory would be the global namespace, and the pathname separator would be ->. Thus, the names $cart->items and $another_cart->items name two different variables. Note that the variable is named $cart->items, not $cart->$items, that is, a variable name in PHP has only a single dollar sign.

// correct, single $
$cart->items = array("10" => 1); 

// invalid, because $cart->$items becomes $cart->""
$cart->$items = array("10" => 1);

// correct, but may or may not be what was intended:
// $cart->$myvar becomes $cart->items
$myvar = 'items';
$cart->$myvar = array("10" => 1);

Within a class definition, you do not know under which name the object will be accessible in your program: at the time the Cart class was written, it was unknown that the object will be named $cart or $another_cart later. Thus, you cannot write $cart->items within the Cart class itself. Instead, in order to be able to access it's own functions and variables from within a class, one can use the pseudo-variable $this which can be read as 'my own' or 'current object'. Thus, '$this->items[$artnr] += $num' can be read as 'add $num to the $artnr counter of my own items array' or 'add $num to the $artnr counter of the items array within the current object'.

Huomaa: There are some nice functions to handle classes and objects. You might want to take a look at the Class/Object Functions

User Contributed Notes
Classes and Objects
add a note about notes

17-Dec-1999 06:48

Here is some code to demonstrate member objects and inheritance.

class ParentObject {
    var $value;

    function ParentObject() {
        $this->value = 42;
    }
}

class MemberObject extends ParentObject {
    var $string;

    function MemberObject() {
        $this->string = "This is a test string.";
	$this->ParentObject();
    }
}

class ObjTest {
    var $ObjPointer;

    function ObjTest() {
        $tmp = new MemberObject;
	$this->ObjPointer = $tmp;
    }
}

echo "Creating object of type ObjTest...";
$object = new ObjTest;
echo "Done.
\n"; echo "String Contents: " . $object->ObjPointer->string . "
\n"; echo "Value Contents: " . $object->ObjPointer->value . "
\n";


05-May-2000 12:13

Note that you can refer to class members with variable variables -
something that makes up for the lack of pointer. The following would yield
"Hello world" -

class a {
var $b;
}

$object = new a;
$object->b = "hello";
$member_name = 'b';
echo $object->$member_name;
$object->$member_name = " world";
echo $object->$member_name;


17-May-2000 08:30

Quel spectacle! Anyway, in PHP, objects are copied when you perform the
assignment operation. The line $a = $b yields two distinct, unrelated
objects -- $a and $b. To reference the same object with different
variables, use ampersands. e.g. $a = &$b; This only works in PHP4
however.


23-Jul-2000 06:10

"Why passing arguments by reference doesn't work within a
class":

The problem lies not with the referenced argument but with the testVar
member of the Test class.
This variable is NOT a reference so when you assign the parameter to it,
it copies the string to it.

from a test i did .. you should simply change the setTestVar() function to
this:

$this-testVar = &$ref;

NOTE: i'm pretty new to the PHP world and can't certify that what i say is
right but it is my assumption based on my experience with other
programming languages.


06-Sep-2000 06:31

[Editor's note: This comment is notcorrect for PHP4, there is a way of
calling the parent method, by using the "parent::method()"
syntaxis, e.g:

class a {
	function init() {
		echo "FOO";
	}
}

class b extends a {
	function init() {
		a::init();
		echo " and BAR";
	}
}

$o = new b;
$o->init();

Which will print: "FOO and BAR"]

Actually the comment left by [email protected]  is correct.
[email protected] is mistaken.

You CANNOT call an overloaded parent function without trickery.

For example:
class a
{
function init(){}
}

class b extends a
{
function init(){}
}

How would you call a->init() from b ?


13-Sep-2000 10:15

-------------------------------------------------
[Editor's note: class casting per se is not part of the object/class
implementation in PHP, but code like the one in this note can kludge if
you need it for very simple cases, more complex ones are left to the
imagination of the programmer:
<?php 
class foo {
	function foo($name="foo") {
		$this->name=$name;
	}
}

class bar extends foo {
	function boom() {
		echo "BOOOM!";
	}
}

$f = new foo(); 
$temp = explode(":",serialize($f));
$temp[2] = "\"bar\"";
$b = unserialize(implode(":",$temp));

$b->boom();

?>
This forces $b to be an instance of "bar" using an object $f, an
instance of "foo"]
-------------------------------------------------


About casting of object, say, i got:

class A extends B {
        function A() {
                $this->B();
        }
        ....
}

$b = new B();
$a = new A();

I wanna have a object of class A with "content" of $b:
$a = (A) $b; // not a valid code,(right?) as for illustration.


08-Oct-2000 11:12

Here's a very important reminder to those of you used to Java/C++ object
references/pointers. When you send a function arguments which include a
class object, PHP will make copies of that object for use inside that
function.

This differs from passing a Java reference to an object or passing a C++
pointer to an object. Within the scope of the above-mentioned function,
calling class methods of the argument object will only affect the copy
that PHP creates. Likewise, when the function itself is completed, the
copy of the object you passed ceases to exist.

To emulate Java/C++ functionality of arguments that are objects, you just
have to modify the given function's signature from this:

function foo(..., $object, ...)

to this:
function foo(..., &$object, ...)

The ampersand(&) thus signifies that the function should receive a
reference to the object, instead of creating a copy of the object.


12-Oct-2000 12:19

A short comment on classes [this maybe is an answer on some previous
posts.
In PHP4 [I havent tested it on PHP3]
You can't have executable code within the class declaration. Here is what
I mean:

define( MY_VAR_1, 4 )
define( MY_VAR_2, 15 )
class classMyWork
{
    var $nClassVar = MY_VAR_1*MY_VAR_2;
    var $nClassVar = MY_VAR_1*10;
    //BOTH WON'T WORK
    var $hOtherClass = new classOtherClass();
    //THIS WON'T WORK TOO
}

Obvoiously there's no syntactic sugar as found in Java or C++
All initialization should be performed in the class constructor
And maybe the assignment of a global variable to a class member is the
same problem


17-Oct-2000 10:48

[Editor's note: function's and method's names are *not* case sensitive in
PHP, this is a known characteristic of the language, so it is no wonder
that the behavior commented here was observed.]

CORRECTION FROM THE PREVIOUS POST

I noticed the following:

class a {
 
 function something() {
  echo "class a something";
 }
}

class SomeThing extends a {
 function SomeThing (){
  echo "SomeThing constructor";
 }
}

mySomeThing=new SomeThing;
mySomeThing->something();

would output 
SomeThing cunstructor
SomeThing cunstructor

instead of 
SomeThing cunstructor
class a something

I had to rename the function in class a to aSomething and call it with
mySomeThing->aSomething() to get it to work properly.  I am using php3,
and I don't know if this was fixed in php4


31-Oct-2000 09:32

eval () can be handy in getting around quirks or limitations with the PHP
parser.

To call a variable method with the name of the method stored in a class
variable try:
  eval("\$this->".$this->nameofmethod."();");

The other more straighforward ways of doing this allong the lines of
$this->$variablefunction () don't seem to work.


01-Nov-2000 05:33

[Editor's note: This has to do with the ambiguity of the expression used.
When the assignment fails it is because the expression could mean
"the property 'tuut' of the object '$this->memberobject'" or
"the property 'memberobject->tuut' of the object '$this'",
parsing of variables inside quotes in which you have a complex expression
is not recommended, the way it should be done is by using the
concatenation operator, which is why the last assignment works. This is a
know behaviour, see for example the "Variable variables" section
of the manual.]


i might be wrong here, but to me it seems that (within a method) something
like this:

$bla = "boink and $this->tuut";

does work, but not this:

$bla = "boink and $this->memberobject->tuut";

I had to resort to

$bla = "boink and ".$this->memberobject->tuut; 

in this case.


07-Nov-2000 11:25

I found a good link for newbies to OOP at www.whatis.com. 

The link is 
-CH


08-Nov-2000 11:33

It seems that when you use "extends", the definition of the
extended classe must precede the use of "new", otherwise it
whon't work.
Which is not the case with a not extended class. (php4)


20-Dec-2000 12:06

It seams as though php 4.0 is NOT case sensitive when it comes to class
names or constructors.

for example:
<?
class BOB {
 function bob () 
 {
 echo 'bob
'; } function BoB () { echo 'BoB
'; } } $bob = new Bob(); /* output BoB */ ?>


22-Dec-2000 03:23

Defaulting a function parameter to a variable isn't directly supported, but
here's how to get around that:

Suppose you have a class:

class query {
   var $sql;
   var $link;

   function go ($SQLstring = $this->sql)
   {
     return mysql_query($this->sql,$link);
   }
}

This doesn't work.  Here's the workaround:

(function spec):
   function go ($SQLstring)
   {
     if (isset($SQLstring)) { $this->sql = $SQLstring; }
     return mysql_query($this->sql,$this->link);
   }

This may not be the best example of this, but I thought I'd throw this out
for you folks ... should allow support of presetting of an object value
and then execution of the method on that, or something like
query::go("SELECT ...");

Enjoy!

p.s. (in this case query::go wouldn't work because it is coded with
$this->link, but if you wanted to just use the default connection, it'd
work fine :)


31-Jan-2001 04:08

I just went through all sorts of playing around with the PHP object
inheritance, and the following is the best way to call an overloaded
parent function as far as I can tell:

  class a {
    function init() {
      echo "A init
"; } } class b extends a { function init() { a::init(); echo "B init
"; } } $x = new b; $x->init(); This will output: A init B init by calling the init() function of a within the init() function of b through the use of a::init() and it seems to work just fine.


31-Jan-2001 11:55

[SORRY my last post wasn't complete,
please delete it...]

SUBJECT: php and "call by reference"

Referencing Objects in PHP ist a nightmare ;-) There is almost nothing
about this in the manual.

To get the same behaviour in php as it is in Java (where you have
"call by reference" by default) use the following syntax:

* add & to all variables you don't
  want to copy, but refer to.
  [$first = &second]
  -> this _is_ in the manual, I'm only
     adding it for completeness.

* add & to all variables in a function
  -declaration you don't want to copy
  "into" the function but refer to
  them from inside the function.
  [function foo(&$first, &$second) {}]

* add & to all function-declarations
  in case you want the functions to
  _return_ referenced variables as
  well (!)
  [function &foo(&$first, &$second){}]

Now it seems possible to write REAL OO-code like in Java. But still, the
more complex structures (built using the above) get, there are strange
effects like mixed up object-references sometimes.

Ferdinand
[Sorry for my english...]


14-Feb-2001 02:33

You can also store object variables as session variables, so that you don't
have to create an object every time the page loads.

Let's see how:
here is my simple class file:

// simple.lib.php
class simple
{
  function dummy
  {
    print "TEST SUCCESSFUL!\n";
  }
}

Then, I create a simple .php which starts a new session and registers the
object-variable of the "simple"-class.

// test1.php
require ("simple.lib.php");
session_start();
session_register("CLASSOBJ");
$CLASSOBJ=new simple();

That's all.
In the following .php-files you've only to add the following lines:
require("simple.lib.php");
session_start();

To test out if it works, simply call:
$CLASSOBJ->dummy(); 
and it will print the message.

I tried it out also with quite huge classes, and it always worked (I think
the pointer to the instanciated class is stored and the class object
itself won't be deleted if you eg. change to another .php-page)


18-Feb-2001 01:40

[Editor's note: PHP is a scripting language, and thus the object is
associated with the variable containing it. To destroy an object, just
assign to the variable, or use unset(), as you would with any other
variable in the language. This should be clear from reading the
introductory material on the language in this manual.]

I could not find any mention about destructor. What good is an class that
does not have a destructor ? Does any one know of any trick to accomplish
the same functionality as that of a destructor ?


19-Feb-2001 12:15

[Editor's note: Remember tha PHP is not a hard core OOP language, and even
the ones that are do not always support the unusual vector/array
references applied to results from methods.]

It seems there is no way to access the return value of a method (or any
function) inline, without assigning it to a variable.

For example:

class Test
{
  function blah ()
  {
     return array(1,2,3);
  }

  function childTest ()
  {
     return new Test;
  }
}

$test = new Test;

// This does not work:
$foo = $test->blah()[0];

// Instead have to do:
$temp = $test->blah();
$foo = $temp[0];

// Similarly for objects, cannot do:
$foo = $test->childTest()->blah();

// Instead have to do:
$temp = $test->childTest();
$foo = $temp->blah();


:-(


23-Feb-2001 07:47

[Editor's note: Just a quick comment.

Inherently OO languages should theoretically access attributes using
methods, but even in existing ones this is not strictly enforced. PHP is
*not* and inherently OO language, but one that has some object/class
support.

This note is talking about a "best practice" recommendation, not
a necessity that is dictated by the language design or implementation.]


In many exemples (and in the official doc) I saw a problem: many access
directly the attributs of the objects. Actually we SHOULD always access an
attribut through a method.

<?php
class user{
  var $_name;
  var $_email;

  function user($name,$email){
    $this->_name=$name;
    $this->_email=$email;
  }

  function getName(){
    return($this->_name);
  }

  function getEmail(){
    return($this->_email);
  }

  function setName($name){
    $this->_name=$name;
  }

  function setEmail($email){
    $this->_email=$email;
  }
}

$me = new user("Bill","[email protected]");
echo "my name is
:".$me->getName()."&lt;br&gt;";
echo "and my email
:".$me->getEmail()."&lt;br&gt;";

//wrong way
$me->_email="[email protected]";
//Better way
$me->setEmail("[email protected]");

//wrong way
echo "oops sorry, here is the right
one:".$me->_email."
"; //Better way echo "oops sorry, here is the right one:".$me->getEmail()."
"; ?> As you noticed I put a "_" at the beginning of the attributs' names, this is a typo tip to declare them as private. OF course this is not real as PHP doesn't support the notions of public, private for methods and attributs. A poor solution waiting for a better one. :)


02-Mar-2001 12:07

[Editor's note: It is understandable that your original loop will not work,
you are getting a *copy* of the object, not the original object itself.

A loop such:

for ($i=0; $i<count($header); $i++)
	$header[$i]->set_i('new string');

will access the object directly, instead of the copy you get w/ foreach.]

Array of Objects

First here is a simple class:
class text {
	var $i;
	function text($i = 'default') {
		$this->i = $i;
	}

	function set_i( $i ) {
		$this->i = $i;	
	}
}

Now create objects and put them in an array
$header[] = new text('foo');
$header[] = new text('bar');

The following will NOT work:

foreach($header as $i):
	$i->set_i('new string');
endforeach;

You must do the following instead:
$j = 0;
foreach($header as $i):
	$k = &$header[$j++];
	$k->set_i('new string');
endforeach;

It's quirky. Does anyone know of a better way to do this?


07-Mar-2001 11:15

Something curious to note...
It seems you cannot call a parent object method via an eval() call.

Example:

class Math
{
    function mul($x, $y)
    {
        return ($x * $y);
    }
}

$result = Math::mul(5, 6);           # works
$result = eval("Math::mul(5, 6);");  # doesn't work


12-Mar-2001 12:27

[Editor's note: See a sample destructor implementation in the section of
the manual dealing with the PEAR code]

Concerning the comment on desctructors: [Editor's note: ... To destroy an
object, just assign to the variable, or use unset(), as you would with any
other variable in the language. ...]: this does not allow to execute an
action on destroying an object. One might want to clear temporary files
etc on object destruction. I understand that there is no way to do so with
PHP 4.0, is that correct?

18-Mar-2001 06:33
I wondered why the "new" assignments in these examples were never
tested for success --- ie.  if(!($var = new Cart())) echo
"failure";

Now I know (at least for PHP4.0.4pl1).

The test ALWAYS fails unless the constructor of the class does a local
member variable assignment.

This I don't like.  Could someone please explain to me why this is a
"good thing"?


03-Apr-2001 10:57

In php objects are stored as associative arrays.
Empty arrays are false by definition (most likely from PHP's perl
heritage).

I believe what you are looking for is:
$var = new Cart();
if(!isset( $var )) echo "failure";

This is a very handy feature for writing hard to read code (i.e. job
security).
But seriously, it is useful for distinguishing null from zero, or in this
case:
the object was not created succesfully ( isset($var) returns false, the
null case)
-from- 
the object was created but not successfully initialized ( isset($var)
returns true  but $var is false, the zero case)

DanRichter.at.programmer.dot.net
10-Apr-2001 04:32

If you get the impression that your constructor is not being called,
remember the proper syntax for member variables: $this->foo. I spent
about a half hour wondering why my constructor "wasn't being
called", and finally found out that the variable assignments in the
constructor were in the form of $foo = $bar, and so simply created
transient variables. (Another possibility: remember that a subclass does
not automatically call its parent class's constructor.)


11-May-2001 05:41

[Editor's note: to avoid this type of problems, you should be using
include_once() instead, see the appropriate manual page entry]

Hi there... Something I noticed ...

If you have a Class A which
requires Class B (eg. require ('B.inc'); )
If you have two more classes extending A:
Class C extends A
Class D extends A 
you may run into some problems if your script requires both C and D, - you
will get an error saying you are redefining Class B.  The solution is to
require only class C or class D in a script.


11-Jun-2001 10:27

The _Note_ on this page is very misleading.. it says "In PHP 4, only
constant initializers for var variables are allowed. To initialize
variables with non-constant values...", it appears (unless someone
can show me otherwise), that you can not even use var $something =
CONSTANT, in a class, and after a heated discussion on #php on
openprojects.net, I thought I should post this so others would just accept
that _all_ var $stuff must be initialized in the constructor.  The _Note_
would leave you to believe some do not, which I have found to be untrue.


13-Jun-2001 03:02

Event Driven!!!!!!!

<?
// ============ your class (anywhere) =======================
class a {
	var $t;

	function lets_call() {
		if (!empty($this->t))
			call_user_func($this->t);

	}
}

//================= your codes ===============================
$new_class=new a;

function ex_one(){
	echo 'ex_one function' .'
'; } function ex_two() { echo 'ex_two function'.'
'; } $new_class->t='ex_one'; $new_class->lets_call(); $new_class->t='ex_two'; $new_class->lets_call(); // ==================== That's all ============================== ?>


30-Jun-2001 12:14

Here is a simple example of a class that represents a row in a MySQL
database.  I have been using this format for all my work on a large data
driven site for some months now and it is _really_ useful.

<?php

class Node {

	var $db;
	var $id;
	var $person;
	var $lastChanged;
	
	function Node ($db, $id, $person = false) {
	//Creating a software object with no ID means that it is not yet in the
database
	//Call commit() on it later to save it to database.
		
		$this->db = $db;
		$this->id = $id;
		if ($id) {
			$sql = "SELECT * FROM Node WHERE nodeID=$id";
			$res = $db->query("node.inc", $sql);
			$dbObj = mysql_fetch_object($res);
			if ($person) {
				$this->person = $person;
			} else {
				$this->person = $dbObj->person;
			}
			$this->lastChanged = $dbObj->lastChanged;
		}
		else {
			$this->person = $person;
		}
	}
	
	function commit () {
		if ($this->id) {
			$sql = "UPDATE Node SET " .
					"person = $this->person " .
					"WHERE nodeID = $this->id";
			$res = $this->db->query("node.inc", $sql);
		}
		else {
			$sql = "INSERT INTO Node VALUES " .
					"(NULL, $this->person, NOW())";
			$res = $this->db->query("node.inc", $sql);
			$this->id = mysql_insert_id($this->db->connID);
		}
		return $this->id;
	}
	
	function erase () {
		if ($this->id) {
			$sql = "DELETE FROM Node WHERE nodeID = $this->id";
			$this->db->query("node.inc", $sql);
		}
		else {
			echo "Error: no known node record to delete.";
		}
	}
}
?>


30-Jun-2001 04:57

By the way, here are some examples of use of my class Node above to show
how easy it makes life with classes and databases:

//To create a new database record:
$node = new Node ($db, false, $persID);
$node->commit();

//To read existing database data:
$node = new Node ($db, $nodeID);
$persID = $node->person;

//To overwrite existing database data:
$node = new Node ($db, $nodeID, $persID);
$node->commit();

Notes:
------
A.  If you can't guess what my database class looks like ($db above is an
instance of it), contact me and I'll let you know.

B.  Node is a very simple example with only one important field.  Real
tables and their corresponding classes have more fields and soon sprout
more specialised methods too.  

C.  Note the four-line if($person) block in Node's constructor - you need
one like that for just about every column in your table.


08-Jul-2001 03:22

If you need a destructor, perhaps it is an idear to simulate it this way
with a global Destroy-Function:

<?
function DestroyObject ($name)
{
     $theobject = &$GLOBALS[$name];
     if (method_exists ($theobject,"Destroy"))
          $theobject->Destroy ();
     unset ($GLOBALS[$name]);
}

class xyz
{
    var $somevar;

    // ### This is the constructor
    function xyz ()
    {
    }

    // ### This is the destructor which will be called
    function Destroy ()
    {
       echo ("Now we destroy it !");
    }

    function SomeDo ()
    {
       echo ("doing something: ".$this->somevar);
    }
}

$example = new xyz;

// .... doing something here 
$example->somevar = 3;
$example->SomeDo();

DestroyObject ("example");

// ### Test => should produce an error !
$example->SomeDo ();

?>


22-Jul-2001 05:35

Need to turn all post and get variables into properties of a class? Here's
how:

class Params {
  function Params() {
    global $HTTP_POST_VARS, $HTTP_GET_VARS;
    $params = array_merge($HTTP_POST_VARS, $HTTP_GET_VARS);
    foreach($params as $k=>$v) {
      $this->$k = $v;
    }        
  }
}

$test = new Params();
foreach(get_object_vars($test) as $k=>$v) {
  print("$k => $v : ");
}

'course, if you've got any class variables with the same name as a get or
post variable, you've just clobbered it, but used with care it's handy.


17-Aug-2001 02:19

You cannot instantiate objects from classes as below:

class UserInformation_mysql{
        var $useridnr, $userid, $sessionID;
        }
class UserInformation_imap{
        var $userid, $pass, $sessionID;
        }
class UserInformation_pgsql{
        var $useridnr, $userid, $sessionID;
        }


if(defined("SISMAIL_MYSQL")){
define("USER_INF_CLASS","UserInformation_mysql");
}

$UserInformation = new 'USER_INF_CLASS'; 

and expect it works... 
but in my opinion, it should work.....


17-Aug-2001 04:49

Thanks to Robin for his solution:
____________________________________
well... maybe. Constants aren't replaced inside a string though, and class

names aren't quoted so there's scope for confusion there.

If you absolutely have to use a constant to carry your classname, the only
way 
I can think of doing what you're asking is to replace the last line of
your 
code with this:

$UserInformation = eval( 'return new ' . USER_INF_CLASS . ';' );

hope this helps.

   -robin
___________________________________


22-Aug-2001 07:35

[Ed. note:  default is a keyword in PHP (used with switch()) and therefor
can't be used as a function- or methodname.]

It would appear that no class method can be called 'default()'.  PHP
generates an error if you attempt the following:

class MyClass
{
function default()
{
...
}
...
}


06-Oct-2001 08:07

You can set object properties to have default values.  As long as those
values don't come from some other variable.

for example

class foo{

var $test1 = "test";
var $test2 = "test2";

}

would be legal

but

class foo{

var $test1 = $GLOBALS[PHP_SELF];
var $test2 = $GLOBALS[HTTP_HOST];

}

would not be legal


16-Oct-2001 12:52

$class->propertyObject->method() 

In case you're wondering, PHP 4 has no problem with chaining -> to
refer to properties/methods of objects which are themselves properties of
other objects. E.g., I was setting up a database class which wanted to
know a couple of related records:

In the 'dbRecord' constructor: 
$this->child = new child_type($this->value("childFKey"));
In the main code:
$record = new parent;
echo $record->child->childMethod();
...works just fine :-) May be obvious to some, but it's not explicitly mentioned and I was a bit worried it wouldn't work 'cause I really need it! (I guess it follows from the same way you do $multiArray[][] to get at multidimensional array indices.)


28-Oct-2001 11:56

A very simple class builder utility is at 


29-Oct-2001 08:29

If you want to call a method of class and you do not have an instance of
the class and you have the class, method name, or both stored in a
variable(s) you can use the following ...

call_user_func( array( $className, $functionName ), [ $param0 [, $param1
[, ... ] ] ] )

For example

$class = "MyClass";
$method = "myMethod";

call_user_func( array( $class, $method ), 0, 1 );

is equivalent to

MyClass::myMethod( 0, 1 );


05-Jan-2002 05:21

It's possible to 'redefine' a class using $this.

Check this example :
<?

class A {
	function A() {
		print "<div>instance of A</div>";
	}
	function whoami() {
		print "<div>";
		var_dump($this);
		print "</div>";
	}
}

class B {
	function B() {
		print "<div>instance of B</div>";
	}

	function transform() {
		$this = new A(); // <-- THIS line :)
	}
	function whoami() {
		print "<div>";
		var_dump($this);
		print "</div>";
	}
}

print
"<div><b>Instanciations</b></div>";
$A = new A; $A->whoami();
$B = new B; $B->whoami();

print
"<div><b>Transformation</b></div>";
$B->transform();
$A->whoami();
$B->whoami();
?>

First, we create two objects : $A -> class A, and $B -> class B.

But the method 'transform' redefines $B instances, and $B is now of class
A.

(sorry, there are some problems with the layout)


08-Feb-2002 09:25

If your new to PHP classes, beware of the scope of variables.  

In particular, if a variable is defined as an implicitly static variable
for the class as a whole, make sure you use the $this->my_var syntax,
not just $my_var.

First, using the scope WRONGLY:

class my_wrong_class
{
  /* A general class variable */
  $db_link;

  /* A constructor function for the class */ 
  function my_class()
  {
    /* this will give the $db_link variable a value   */
    /* but only as a local variable in this function. */
    $db_link = mysql_connect('localhost','root','');    
  }

  function do_something()
  {
    $query = "SELECT * FROM my_table";

    /* Again, the $db_link reference is wrong!  Won't work */
    $result = mysql_query( $query, $db_link );
  }
}

Now doing the scope CORRECTLY:

class my_right_class
{
  /* A general class variable */
  $db_link;

  /* A constructor function for the class */ 
  function my_class()
  {
    /* Ah! Correctly references the class variable */
    $this->db_link = mysql_connect('localhost','root','');    
  }

  function do_something()
  {
    $query = "SELECT * FROM my_table";

    /* Ah! Correctly uses the class variable */
    $result = mysql_query( $query, $this->db_link );
  }
}

If you are a seasonsed PHP programmer you may say nobody would do that.  I
as a seasoned non-PHP programmer did, couldn't understand why my code
didn't work, and fudged it, till now...


15-Feb-2002 01:58

(only tested w/ php4.1.0 w/ apache 1.3.20)

It appears that you don't have to declare your vars inside a class, even
if you want to serialize an instance of the class.  From within any
function including the constructor, calling
$this->foo = $bar;
will create an object var in your class, even if there is no class var
named foo declared in your class.  If you serialize the object, for
example to register it with the client's session or put it in a database,
the object var will remain!


28-Feb-2002 03:26

It's possible to extend a class in PHP, from a class made with Visual Basic
in a DLL.

Read the post saying "It's possible to 'redefine' a class using
$this".

EXAMPLE:

1) Create a class in Visual Basic like this:

   Project Name: projectA
   Class Name: ClassA

Public strPP As String

Private Sub Class_Initialize()
   strPP = "Inicializado"
End Sub

Public Function a() As String
   a = "A_" & strPP
End Function

2) Create a class in PHP like this:

<?
  class classB
  {
    function classB()
    {
      // Cambio el puntero de esta clase, por el de la clase de Visual
Basic
      $this = new COM("projectA.classA");
    }
  }

  $B = new classB;
  echo $B->A()."
"; // Uso el metodo A() de la clase de Visual Basic classA $B->strPP = "Hola!!!"; // Propiedad strPP de la clase de Visual Basic classA echo $B->A()."
"; ?> 3) Execute it! It should output this: A_Inicializado A_Hola!!!


01-Mar-2002 04:52

When trying to use a dynamically named array in a class, be careful of how
you access your dynamic array.

Incorrect:
$dynamic_name="myarray";

$this->$dynamic_name[0]="apples"; 
// Meant $this->m="apples";

$this->$dynamic_name[1]="oranges"; 
// Meant $this->y="oranges";

Correct way:
$dynamic_name="myarray";

$this->{$dynamic_name}[0]="apples";  
// Meant $this->myarray[0]="apples";

$this->{$dynamic_name}[1]="oranges"; 
// Meant $this->myarray[1]="oranges";

The incorrect example written differently shows how you could interact
with multiple dynamic variable names.
$dynamic_names=array("name_one","name_two");

$this->$dynamic_names[0]="apples"; 
// Meant $this->name_one="apples";

$this->$dynamic_names[1]="oranges"; 
// Meant $this->name_two="oranges";

However this example might be more clearly written as
$dynamic_names=array("name_one","name_two");

$this->{$dynamic_names[0]}="apples"; 
// Meant $this->name_one="apples";

$this->{$dynamic_names[1]}="oranges"; 
// Meant $this->name_two="oranges";

joey at creativejuices dot ws
22-Mar-2002 06:26

In case you need to, here is how you can do Class variables in addition to
Instance variables in php 4.1.2.

class MyClass{
var $classcount = 0;
var $objName;

	function MyClass(){
	global $classcount;
		$classcount++;
	}

	function setName($theName){
		$this->objName = $theName;
	}
	
	function getName(){
		return $this->objName;
	}
}

$class1 = new MyClass;
$class1->setName("class1");
echo "First Class Name: ".$class1->getName();
echo "First Class Count: ".$classcount;

$class2 = new MyClass;
$class2->setName("class2");
echo "Next Class Name: ".$class2->getName();
echo "Next Class Count: ".$classcount;

/***************
This will yield:

First Class Name: class1

First Class Count: 1

Next Class Name: class2

Next Class Count: 2

***************/


27-Mar-2002 04:02

There is a great solution for "plugin" API developer's wich
didn't know how a extended class would be called later, but likes to use
ones.

It's a little tricky way of using a interface_class and the variable
variables. I just like to throw you into water and let you learn from
following example:

[example]

class my_interface{
   function foo($msg){
      /*it does nothing, and it could be totally ignored.. but it is a
help for the class definitions. Just to prevent that things get messed up
when "plugin" developers play the "try/error" game...
*/
   }
}

class foobar extends my_interface{
   function foo($msg){
      echo "foobar:: $msg";
   }
}

class hello_world extends my_interface{
   function foo($msg){
       echo "we say hello and '$msg' to the whole world";
   }

}

// now the interesting part :)
$used_interface = "foobar";
$obj = new $used_interface ();
$obj->foo("hallo");
[/example]

Now... try to set up other my_interface childs... the interesting thing
ist the variable "$used_interface"!

You must insert a valid class name into this variable, otherwise you get
an "cant instanctiate class... " error. So, now,  you can create
a class only by knowing it's name - without hardcoding!

Why the hell using an interface class? Well... see it as an help... for
you and for the plugin developers. The plugin dev's will know what the api
want's, and you know what your api could process... ;)

It works fine under php 4.0.6.

Greetz

s.hagenbrock

Btw... don't forget to include the class files. Else you get an
"undefined class" error ;)


05-Apr-2002 03:17

The returned result from a constructor cannot be accessed: the result of
the call to new is the instantiated object.

So error handling in a constructor is problematic.  There are a few ways I
can think of handling this:
1) call exit() or die() in the constructor -- not good if you want to
recover and carry on somehow
2) don't put code that can fail in the constructor, put it in an
initialisation function instead which can return an error result --
somewhat defeats the purpose of a constructor (it shouldn't really be
possible to construct an object with uninitialised state)
3) when an error occurs, save that state inside the object to be returned
using isError and getError functions.  Ideally all other functions should
refuse to do their job if an error occurred during construction.

I guess this is one of the reasons that Java has exceptions.


17-May-2002 05:18

Despite the comments above this works out very well for me

class CTest {
  function CTest() { }
  function go( $var ) {
     echo "Thats an ".$var;
  }
}

$cTest = new CTest;

$member = "go";
$class = & $cTest;

$class->$member( "whatever" );


30-May-2002 12:25

Hello.

I have defined a class for querying a database called
"db_query".
When you instantiate the class using
$myQuery = new db_query ($sql, $datasource);
The results of the query are available from
$myQuery->column[$row]

now my point is; By the strict definition of a class declaration, you have
to declare ALL the properties outside the methods. However, in this
instance, it's impossible to declare the properties of the column headings
before you've executed the query in the method.
I expect it's VERY illegal to declare properties from within the method
itself, so, is there a way around this, or is it okay to do it this way?


04-Jun-2002 05:14

Know of any basic tutorials on PHP Classes and OOP?
* 


11-Jun-2002 10:25

Just tried finding out some solution for the following code, not working:

[example]
<?
	class bar 
	{
		var $name;
		
		function getName()
		{
			echo $this->name;
		}
	}

	class foo
	{
		var $bar_field;
		
		function setElement ( $newBar )
		{
			$this->bar_field = $newBar;
		}
		
		function getElement ()
		{
			return $this->bar_field;
		}
	}
	
	$test_bar = new bar;
	$test_foo = new foo;
	
	$test_foo->setElement($test_bar);	// NOT WORKING
	
	$test_foo->getElement()->getName();	// NOT WORKING
?>

Found nothing documentated since now, anyone knows a friendly or maybe
even clean solution??


12-Jun-2002 02:08

Solution for Tobias' Problem:
> $test_foo->getElement()->getName();	// NOT WORKING

$test_baz =& $test_foo->getElement();
$test_baz->getName(); // WORKING!


12-Jun-2002 06:00

Hi again!

Thats a good workaround, but what about setting Element-Data? 

Think about:

$test_baz =& $test_foo->getElement();
$test_baz->setName("blah");

Will this set the Value of my $test_bar inside $test_foo, or just the
Value of the Copy?

How to workout this??

Thanks for the Help!
P.S.: I have allways done Functional-Programming in PHP, not OOP....
sorry!


17-Jun-2002 02:02

Tobias:
*tic*

You mean procedural programming, not functional programming.

Functional programming is a different kind of programming language.
Haskell is an example of a functional programming language. (In case you
wanted to look it up).


20-Jun-2002 10:26

I'm working with a couple of different types of objects.

On a whim, I tried to execute this code as the ctor for a class:
function db_user($serial)
{
   $temp=new db_query("SELECT <STUFF>");
   $this=$temp->get_result();
   $temp->free_result();
}

Can someone please explain to me why the '$this->..." line works,
and if it's supposed to work this way? When I execute that code, all
existing methods and members of the class are erased, and replaced with
the ones from the rh side of the assignment. However, the function still
continues to execute.

Neat feature, or odd quirk? Will this behavior change in future versions
of PHP?


22-Jun-2002 08:29

Given lack of type checking I understand why it is necessary to use $this
every time you access a member variable in a class; but this is a serious
gotcha for those used to coding in C++/Java where you can refer to the
variable name only.  I am also submitting a feature request that a warning
be generated where a variable name is used in a class that matches a class
member variable name.

add a note about notes
previousVariable functionsextendsnext
Last updated: Tue, 28 May 2002
show source | credits | stats | mirror sites:  
Copyright © 2001, 2002 The PHP Group
All rights reserved.
This mirror generously provided by:
Last updated: Thu Jul 4 12:06:15 2002 CEST