User Contributed Notes Classes and Objects |
|
[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()."<br>";
echo
"and my email
:".$me->getEmail()."<br>";
//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 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>" ); ?>
|
|
|