PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links 
search for in the  
previousFunzioni variabiliextendsnext
Last updated: Tue, 03 Sep 2002
view the printer friendly version or the printer friendly version with notes or change language to English | Brazilian Portuguese | Chinese | Czech | Dutch | Finnish | French | German | Hungarian | Japanese | Korean | Polish | Romanian | Russian | Spanish | Swedish | Turkish

Capitolo 14. Classi e Oggetti

Classi

Una classe � una collezione di variabili e funzioni che utilizzano queste variabili. Una classe si definisce usando la seguente sintassi:

<?php
class Cart
{
    var $items;  // Articoli nel carrello
   
    // Aggiunge $num articoli di $artnr nel carrello
 
    function add_item ($artnr, $num)
    {
        $this->items[$artnr] += $num;
    }
   
    // Prende $num articoli di $artnr e li rimuove dal carrello
 
    function remove_item ($artnr, $num)
    {
        if ($this->items[$artnr] > $num) {
            $this->items[$artnr] -= $num;
            return true;
        } else {
            return false;
        }   
    }
}
?>

Il codice definisce una classe chiamata Cart composta da un array associativo che archivia gli articoli nel carrello e due funzioni per aggiungere e rimuovere gli articoli dal carrello stesso.

Cautela

Le seguenti note cautelari sono valide per PHP 4.

Il nome stdClass � usato esclusivamente da Zend ed � riservato. Non � quindi possibile creare una classe chiamata stdClass in PHP.

I nomi di funzione __sleep e __wakeup sono riservati e magici nelle classi PHP. Non � possibile creare funzioni con questi nomi nelle classi definite dall'utente, a meno che non sia desiderata la funzionalit� magica connessa a questi nomi. Si veda sotto per avere pi� informazioni.

PHP riserva tutti i nomi di funzione che iniziano con __ a funzioni magiche. Si suggerisce di non usare nomi di funzioni che utilizzano con i caratteri __ in PHP a meno che non si desideri implementare una funzionalit� magica.

Nota: In PHP 4, sono permesse inizializzazioni di variabili con valori costanti solamente grazie all'uso di var. Per inizializzare variabili con valori non-costanti, bisogna creare una funzione d'inizializzazione che � chiamata automaticamente all'istanziazione di un oggetto da una classe. Questo tipo di funzione si chiama costruttore (vedi sotto).

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

/* Questo � corretto. */
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 ... */
    }
}

Le classi sono tipi del linguaggio, e sono modelli per variabili reali. Per creare una variabile oggetto si usa l'operatore new.

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

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

Il codice sopra, genera gli oggetti $cart e $another_cart, dalla classe Cart. La funzione add_item() dell'oggetto $cart � chiamata per aggiungere una ricorrenza dell'articolo numero 10 a $cart. Ad $another_cart sono aggiunte 3 ricorrenze dell'articolo numero 0815.

Sia $cart che $another_cart dispongono delle funzioni add_item(), remove_item() e della variabile $items, ma per ogni oggetto queste sono funzioni e variabili sono distinte. Potete pensare agli oggetti come a qualcosa di simile alle directories di un filesystem. In un filesystem si possono avere due diversi files README.TXT, purch� siano in directories differenti. Cos� come in un filesystem dovete digitare il nome (percorso) completo per raggiungere un determinato file partendo da una directory toplevel, cos� dovete specificare il nome completo di una funzione o variabile che desiderate richiamare da un oggetto. Per PHP, la directory toplevel � il namespace globale dell'oggetto ed il separatore del pathname (/) � ->. Cos� $cart->items e $another_cart->items sono due diverse variabili che differiscono per il nome. Si noti che la variabile si chiama $cart->items, e non $cart->$items, questo perch� le variabili il PHP si scrivono con un unico simbolo di dollaro.

// corretto, con un simbolo $
$cart->items = array("10" => 1); 

// non valido, perch� $cart->$items diventa $cart->""
$cart->$items = array("10" => 1);

// corretto, ma non sempre pu� funzionare:
// $cart->$myvar diventa $cart->items
$myvar = 'items';
$cart->$myvar = array("10" => 1);

Quando si definisce una classe, non � possibile prevedere quale nome avr� l'oggetto istanziato nel programma. Quando la classe Cart � stata scritta, non si poteva prevedere che l'oggetto istanziato da essa si sarebbe potuto chiamare $cart o $another_cart. Quindi non � possibile scrivere $cart->items all'interno della classe Cart in fase di progettazione. Per poter accedere alle funzioni e alle variabili interne di una classe perci� si usa la pseudo-variabile $this che pu� essere letta come 'la mia\il mio' o 'di questo oggetto'. Quindi, '$this->items[$artnr] += $num' pu� essere letto come 'aggiungi $num al contatore $artnr al del mio array degli articoli' o 'aggiungi $num al contatore $artnr dell'array degli articoli di questo oggetto'.

Nota: Ci sono molte utili funzioni per manipolare classi ed oggetti. Se desiderate conoscerle potete dare un'occhiata alle Class/Object Functions

User Contributed Notes
Classi e Oggetti
add a note about notes
[email protected]
17-Dec-1999 07: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";

[email protected]
05-May-2000 01: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;

[email protected]
17-May-2000 09: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.
[email protected]
23-Jul-2000 07: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.

[email protected]
06-Sep-2000 07: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 ?

[email protected]
13-Sep-2000 11: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.

[email protected]
09-Oct-2000 12: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.

[email protected]
12-Oct-2000 01: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

[email protected]
17-Oct-2000 11: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

[email protected]
31-Oct-2000 10: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.

[email protected]
01-Nov-2000 06: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.

[email protected]
08-Nov-2000 12:25

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

The link is
-CH

[email protected]
09-Nov-2000 12: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)

[email protected]
20-Dec-2000 01: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
*/
?>

[email protected]
22-Dec-2000 04: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 :)

[email protected]
31-Jan-2001 05: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.

[email protected]
31-Jan-2001 12: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...]

[email protected]
14-Feb-2001 03: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)

[email protected]
18-Feb-2001 02: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 ?

[email protected]
19-Feb-2001 01: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();


:-(

[email protected]
23-Feb-2001 08: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. :)

[email protected]
02-Mar-2001 01: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?

[email protected]
08-Mar-2001 12: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

[email protected]
12-Mar-2001 01: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 07: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"?

[email protected]
03-Apr-2001 11: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 05: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.)
[email protected]
11-May-2001 06: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.

[email protected]
11-Jun-2001 11: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.
[email protected]
13-Jun-2001 04: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 ==============================
?>

[email protected]
30-Jun-2001 01: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.";
}
}
}
?>

[email protected]
30-Jun-2001 05: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.

[email protected]
08-Jul-2001 04: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 ();

?>

[email protected]
22-Jul-2001 06: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.

[email protected]
17-Aug-2001 03: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.....

[email protected]
17-Aug-2001 05: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
___________________________________

[email protected]
22-Aug-2001 08: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()
{
...
}
...
}

[email protected]
06-Oct-2001 09: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

[email protected]
16-Oct-2001 01: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.)

[email protected]
29-Oct-2001 12:56

A very simple class builder utility is at
[email protected]
29-Oct-2001 09: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 );

[email protected]
05-Jan-2002 06: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)

[email protected]
08-Feb-2002 10: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...

[email protected]
15-Feb-2002 02: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!

[email protected]
28-Feb-2002 04: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!!!

[email protected]
01-Mar-2002 05: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 07: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

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

[email protected]
27-Mar-2002 05: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 ;)

[email protected]
05-Apr-2002 04: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.

[email protected]
17-May-2002 06: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" );

[email protected]
30-May-2002 01: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?

[email protected]
04-Jun-2002 06:14

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

[email protected]
11-Jun-2002 11: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??

[email protected]
12-Jun-2002 03:08

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

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

[email protected]
12-Jun-2002 07: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!

[email protected]
17-Jun-2002 03: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).

[email protected]
20-Jun-2002 11: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?

[email protected]
22-Jun-2002 09: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.
[email protected]
07-Jul-2002 07:32

<?
class testClass
{
var $a;

function printa()
{
echo $this->a;
}
}

$obj[10] = new testClass;
$obj[0]->a = 4;
$obj[0]->printa();
?>

why won't this work?

[email protected]
08-Jul-2002 12:26

$obj = new testClass;
$obj->a = 4;
$obj->printa();

no "[n]".

[email protected]
10-Jul-2002 07:22

In response to [email protected]'s query.

You have defined one element of the $obj variable (element 10) to be the object and then called element 0's object (which wasn't previously set).

To get this to work you need to use the same elements of the $obj variable as below:

$obj[10] = new testClass;
$obj[10]->a = 4;
$obj[10]->printa();

If I'm right, it looks like you wanted to create an array of 10 objects and were trying to use the first one.
From my opinion you'd have to make each element an object for this to work.

[email protected]
17-Jul-2002 08:35

To create an array of objects, try the following:
class Test{
function Test($temp){
$this->a = $temp;
}
function print_a(){
echo $this->a;
}
}

$myObj = array();
for($i = 0; $i < 10; $i++)
$myObj[] = new Test($i);

$myObj[9]->print_a();

Granted there are many ways to create you array. This is just a quick example.

[email protected]
19-Jul-2002 03:36

Don't use $this to pass a reference to the current object in the object's constructor.

class parent
{
var $child;
function parent()
{
$this->child = new child(&$this);
}
}

class child
{
var $parent;
function child(&$parent)
{
$this->parent = &$parent;
}
}

$parent = new parent();

for some reason
$parent != $parent->child->parent

if you need to pass a reference to child objects, use eg. an init-function, in which &$this will work just fine. Just don't use the constructor.

uws (at) xs4all (dot) nl
08-Aug-2002 11:36

The sample code provided above doesn't seem correct to me. The line that says:

if ($this->items[$artnr] > $num)

should be changed to:

if ($this->items[$artnr] >= $num)

Otherwise, you won't be able to remove all items from the cart.

13-Aug-2002 11:13
If you register object class, You must include class file before session started!!
13-Aug-2002 03:23
[Editor's note: There are no real "private" variables/methods in PHP 3 or PHP 4, some functions treat variables/methods whose names start with and underscore as if they were private, but they are still accessible. This is schedule to change when the Zend 2 engine gets released, don't hold your breath just yet ;-)]


Don't know if it's undocumented, or if I just can't find it, but...

yes, you can make private functions/variables!
Just prepend the variable name with an underscore, ie.

var $_myPrivateVar
or
function _myPrivateFunction

[email protected]
21-Aug-2002 01:54

I noticed that you can't define constants inside classes. Didn't see anything about that on this page?!
[email protected]
22-Aug-2002 05:55

If you want to convert an array (for example) to an object, you can do something like this, using the reserved stdClass for data;

<?php
$array = array ( "one" =>"red", "two" => "blue" );
$object = new stdClass ();
foreach ( $array as $key => $val ) {
$object->{$key}=$val;
}

echo ( "<pre>" );
print_r ( $object );
echo ( "</pre>" );
?>

add a note about notes
previousFunzioni variabiliextendsnext
Last updated: Tue, 03 Sep 2002
show source | credits | stats | mirror sites
Copyright © 2001, 2002 The PHP Group
All rights reserved.
This mirror generously provided by:
Last updated: Thu Sep 5 20:07:53 2002 CEST