Функции работы с Классами/Объектами

Содержание

  • call_user_method_array — Вызываем метод объекта с массивом параметров [устаревшее]
  • call_user_method — Вызывает метод указанного объекта [устаревшее]
  • class_exists — Проверяет был ли объявлен класс
  • get_class_methods — Возвращает массив имен методов класса
  • get_class_vars — Возвращает массив свойств класса с их инициализационными значенями
  • get_class — Возвращает имя класса к которому принадлежит объект
  • get_declared_classes — Возвращает массив с именами объявленных классов
  • get_declared_interfaces — Возвращает массив всех объявленных в текущей итерации интерфейсов.
  • get_object_vars — Возвращает ассоциативный массив свойств и значений объекта
  • get_parent_class — Возвращает имя класса базового для объекта или класса
  • interface_exists — Checks if the interface has been defined
  • is_a — Возвращает TRUE если объект принадлежит классу или является одним из его наследователей.
  • is_subclass_of — Возвращает TRUE если объект является экземпляром класса, наследующего данный.
  • method_exists — Проверяет существует ли метод в данном классе
  • property_exists — Checks if the object or class has a property

Коментарии

[Editor's note: If you are trying to do overriding, then you can just interrogate (perhaps in the method itself) about what class (get_class()) the object belongs to, or if it is a subclass of a particular root class.

You can alway refer to the parent overriden method, see the "Classes and Objects" page of the manual and comments/editor's notes therein.]

There is no function to determine if a member belongs to a base class or current class eg:

<?php
class foo {
 function 
foo () { }
 function 
() { }
}

class 
bar extends foo {
 function 
bar () { }
 function 
() { }
}

lala = new Bar();
?>
------------------
how do we find programmatically if member a now belongs to class Bar or Foo.
2001-03-08 03:59:28
http://php5.kiev.ua/manual/ru/ref.classobj.html
If you want to be able to call an instance of a class from within another class, all you need to do is store a reference to the external class as a property of the local class (can use the constructor to pass this to the class), then call the external method like this:

$this->classref->memberfunction($vars);

or if the double '->' is too freaky for you, how about:

$ref=&$this->classref;
$ref->memberfunction($vars);

This is handy if you write something like a general SQL class that you want member functions in other classes to be able to use, but want to keep namespaces separate. Hope that helps someone.

Justin

Example:

<?php

class class1 {
    function 
test($var) {
       
$result $var 2;
        return 
$result;
    }
}

class 
class2{
    var 
$ref_to_class=''# to be pointer to other class

   
function class1(&$ref){ #constructor
       
$this->ref_to_class=$ref#save ref to other class as property of this class
   
}

    function 
test2($var){
       
$val $this->ref_to_class->test($var); #call other class using ref
       
return $val;
    }
}

$obj1=new class1;
# obj1 is instantiated.
$obj2=new class2($obj1);
# pass ref to obj1 when instantiating obj2

$var=5;
$result=obj2->test2($var);
# call method in obj2, which calls method in obj1
echo ($result);

?>
2002-08-19 12:38:51
http://php5.kiev.ua/manual/ru/ref.classobj.html
You may find it helpful in complex projects to have namespaces for your classes, and arrange these in a hierarchical manner.   A simple way to do this is to use the filesystem to order your hierarchies and then define a function like this:

function use_namespace($namespace){

require_once("namespaces/$namespace.obj.php");

}

(lack of indentation due to HTML UI for this page)
This requires that all your object libraries end in .obj.php (which I use) but you can modfy it to suit your needs.  To call it you could, for exmaple call:

use_namespace("example");
or if foo is part of example you can call:
use_namespace("example/foo");
2002-09-14 15:35:25
http://php5.kiev.ua/manual/ru/ref.classobj.html
Something I found out just now that comes in very handy for my current project:

it is possible to have a class override itself in any method ( including the constructor ) like this:

class a {

..function ha ( ) {
....if ( $some_expr ) {
......$this = new b;
......return $this->ha ( );
....}
....return $something;
..}

}

in this case assuming that class b is already defined and also has the method ha ( )

note that the code after the statement to override itself is still executed but now applies to the new class

i did not find any information about this behaviour anywhere, so i have no clue wether this is supposed to be like this and if it might change... but it opens a few possibilities in flexible scripting!!
2002-09-20 17:52:28
http://php5.kiev.ua/manual/ru/ref.classobj.html
FYI: if you want to split your class into manageble chunks, what means different files for you, you can put you functoins into includes, and make include() have a return value. Like this:

class Some_class {
  var $value = 3;
  function add_value ($input_param) {
    return include ("path/some_file.php");
  }
}

And your included file:

$input_param += $this->value;
return $input_param;

Then your function call will be:

$instance = new Some_class ();
$instance->add_value (3);

And this will return
6
hopefully :P

Keep in mind though, that the scope in the included file will be identical to the scope the function 'add_value' has.
And if you want to return the outcome, you should also have a return statement made in your include as well.
2003-07-08 08:24:33
http://php5.kiev.ua/manual/ru/ref.classobj.html
Автор:
to pillepop2003

Why do u want to know the classname of an non-existant object?

The only possible explanation for this question seems to me u want to know the class before u instantiate the object. Well, this is of no use since u always instantiate a class of ur choice. 

When the class is instantiated into an object u can find the class of the object by means of get_class(). This is all u need. In case of inheritance u can use get_class($this) to get the class of the instantiated object. Now u can differentiate according to which class the object belongs to.

e.g.:

<?php
class A{
   function 
A(){
     
$class_of_this get_class($this);
      echo 
'Object is an instance of class '.$class_of_this.' which is the ';
      if(
strcmp($class_of_this,'A')==0)
         echo 
'parent-class';
      else if(
strcmp($class_of_this,'B')==0)
         echo 
'child-class';
      echo 
".\n";
   }
}

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

$object1 = new A();
$object2 = new B();
?>

When u run this code-snippet the output will be:

Object is an instance of class A which is the parent-class.
Object is an instance of class B which is the child-class.
2004-05-28 12:40:53
http://php5.kiev.ua/manual/ru/ref.classobj.html
Re: Looking for an uninstantiated class

# Loads data from a table into a class object
class LFPDataFactory extends LFPObject {
        var $object;
        var $class;
        var $table;
        function LFPDataFactory($args) {
                $this->unpackArgs($args); // assigns locals from $args
                if (in_array(strtolower($this->class), get_declared_classes())) {
                        $this->object = new $this->class;
                        // assemble the columns in the table...
                        // select their values and put them in our new object...
                } else { trigger_error("Class ".$this->class." not found", E_USER_ERROR); }
        }
}
$r = new LFPDataFactory("class=LFPLayout,table=layout");
$new_obj = $r->object; // this is a LFPLayout object.
print_r($new_obj);

This class looks to see if the class exists, then instantiates it -- a declared class is not the same as an instantiated class. As long as LFPLayout exists somewhere in the scripts, get_declared_classes() will find it. Remember strtolower on compare, however.

Why would I do this? Because I have my class layouts the same as their respective tables; the factory then selects the data (making sure that the variables match) and plugs in the data. (I've left out the actual code to do the selection/insertion).
2004-06-18 19:59:05
http://php5.kiev.ua/manual/ru/ref.classobj.html
As programmers, you're probably more organized than me, but, I do try and maintain some order in my classes and codes and separate them in "packages" as in java.
This helped me keep them organized but caused havok when trying to use them, so what I did was to create a class that handles the loading of classes (which I instanciate in all pages) along with my error handling class all bundled up. This way, I can load my classes with a command similar to 
$baseClass->loadClass("package","className"[,"constructor"]);

the function responsible for this has some checking to see if they are loaded and stuff like that...

function loadClass($packageName,$className,$constructor=""){
  // if you dont have a constructor declare any function inside
  // the class
  if ($constructor==""){
    $constructor=$className;
  }
  if(!is_callable(array($className,$constructor))){
    if (defined("CLASS_DIR")){
      $pkg = CLASS_DIR.$packageName."/";
        if (is_dir($pkg)){
          // we have a directory with the package name
          $cls = $pkg.$className.".class.php";
          if(is_file($cls)){
            // we have a file
            include_once($cls);
          }else{
            die("Class <b>$className</b> could not be found in package <b>$packageName</b> , please check your instalation");
          }
        }else{
          die("Package <b>$packageName</b> could not be found, please check your instalation");
        }
      }
    }
}

Just remember to define CLASS_DIR as the physical path for the directories where you packages are...

Hope this comes in handy...

Here's an example of a diretory strucutre...
/var/www/classes/   <- this would be CLASS_DIR
in there I have:
package1/
     name.class.php
     name2.class.php
....

The loadClass would look like: loadClass("package1","name"); 

Cute and easy
2004-07-05 22:58:08
http://php5.kiev.ua/manual/ru/ref.classobj.html
To pillepop2003 at yahoo dot de:

I have the same issue.  I have a base class that manages database tasks for a number of child classes.  One of the functions in the base class is a find() method that returns instances of the child classes.  Since find() is usually called as a static method, it needs to know the name of the child class.  As you've found, this appears to be impossible to get in an easy fashion.

The only way I've found to get the child class name is to use the debug_traceback() function.  This requires me to have a find() method in every child class, but it does work.

Here's an example:

<?php
 
require_once("Application.php");

  class 
parentClass {
    function 
find() {
     
$className NULL;
      foreach (
debug_backtrace() as $bt) {
        if (
$bt['function'] == __FUNCTION__) {
         
$className $bt['class'];
        }
      }

     
// here should be some code to find the proper id, let's assume it was id 1
     
$id 1;
      return new 
$className($id);
    }
  }
 
  class 
foo extends parentClass {
    function 
__construct($id) {
     
$this->id id;
    }
   
    function 
find() {
      return 
parent::find();
    }
  }
 
  class 
bar extends parentClass {
    function 
__construct($id) {
     
$this->id id;
    }

    function 
find() {
      return 
parent::find();
    }
  }
 
 
$a foo::find();
 
printf("Type for \$a: %s<br/>\n"get_class($a));
 
$b bar::find();
 
printf("Type for \$b: %s<br/>\n"get_class($b));
?>
2005-01-02 19:27:03
http://php5.kiev.ua/manual/ru/ref.classobj.html
to covertka at muohio dot edu and pillepop2003 at yahoo dot de:

There's a much easier solution to getting a class' name for working with a factory function.  Let's assume you're doing something like this:

<?php

 
function FactoryFunction($whatever$instancedata) {

    switch (
$whatever) {
      case 
'stuff'      : return new Stuff($instancedata);
      case 
'otherstuff' : return new Otherstuff($instancedata);
    }

  }

?>

Now, consider the named parameter idiom and remember that PHP uses hashes for everything; as a result make the following changes:

<?php

 
function FactoryFunction($whatever$instancedata) {

    switch (
$whatever) {

      case 
'stuff'      : return array('typeis'=>'stuff',      'instance'=>new Stuff($instancedata));
      case 
'otherstuff' : return array('typeis'=>'otherstuff''instance'=>new Otherstuff($instancedata));

    }

  }

?>

Nice 'n simple.  It seems that what the original poster wanted was something like C++ static data members; unfortunately as PHP4 has no static variables at all, there would need to be significant language change to support static-like behavior.  If you move to PHP5, the static keyword solves your problem cleanly.
2005-03-02 12:25:43
http://php5.kiev.ua/manual/ru/ref.classobj.html
Автор:
If anyone is interested in looking for a way to dynamically load existing objects into a class, here is what I found very useful.

//---------------------------------------------------------
// Dynamically load External Objects into a class

  function objRef ( &$obj ) {     
    eval("\$this->obj_".get_class($obj)." = \$obj;"); 
  }
//---------------------------------------------------------
// Reference by using: $this->obj_[object Name]->[var|f{}]

Example:

class date {  function date ( ) { $this->date = "March 3rd"; } }
class time {  function time ( ) { $this->time = "12:30pm"; } }

class show {
    function objRef ( &$obj ){
        eval("\$this->obj_".get_class($obj)." = \$obj;");
    }
   function test ( $var ){
       echo "$var".$this->obj_date->date." @ ".$this->obj_time->time;
   }
}

$date = new date;
$time = new time;
$show = new show;
    $show->objRef($date);
    $show->objRef($time);
    $show->test("Time Now => ");

// Output: Time Now => March 3rd @ 12:30pm

I found the prefix 'obj_' before the class name useful because it helped me to automatically identify external object references when scanning through my scripts. You can omit this if you want. Hope this helps someone.
2005-03-03 15:27:51
http://php5.kiev.ua/manual/ru/ref.classobj.html
((PHP5))

I wanted to dynamically choose an extender for a class.  This took awhile of playing with it but I came up with a solution.  Note that I can't verify how safe it is, but it appears to work for me.  Perhaps someone else can shed light on the details:

<?php

class { var $value "Class A\n"; }
class 
{ var $value "Class B\n"; }

// Uncomment which extender you want.  You can use variables as well.
// define('__EXTENDER__', 'A');
   
define('__EXTENDER__''B');

// Use eval to create a wrapper class.
eval('class EXTENDER extends '__EXTENDER__ ' { }');

class 
extends EXTENDER
{
  function 
__construct()
  {
     echo 
$this->value;
  }
}

$t = new C;

?>

Outputs:   Class B

Practical application:  I have a database abstraction system that has individual classes for mysql, pgsql, et al.  I want to be able to create a global db class that extends one of the individual db classes depending on the application configuration.

I know that there are probably much better ways of doing this but I haven't reached that level when it comes to classes.
2005-06-27 03:08:57
http://php5.kiev.ua/manual/ru/ref.classobj.html
as for zabmilenko's solution:
wouldn't it be better to create it this way?

<?php
// The base class for all db classes
class DB {
 protected 
$connectId;
}

// Class for MySQL, which extends base class
class MySQL extends DB {
 function 
connect () {
 
$this->connectId mysql_connect (...); 
 }
}

// Class for PostgreSQL, which extends base class
class pgSQL extends DB {
 function 
connect () {
 
$this->connectId pg_connect (...); 
 }
}

// and then call constructor like this:
$dbName "MySQL";
$db = new $dbName ( ... );
// ... which creates an object of class MySQL
?>
2005-08-03 01:55:41
http://php5.kiev.ua/manual/ru/ref.classobj.html
Subject: using "sql_calc_found_rows" in a MySQL query while exploiting result in a PHP db class object.

Hello,

There is a nice function in MySQL that allows to know how many records would have been returned if no "where" clause were set : SQL_CALC_FOUND_ROWS.

If you have create a db object to collect the returned lines, you will be a little perplex when trying to call the result of this function.

Why ?
Simply because the returned field's name is "found_rows()" and obviously it's not possible to call something like :

<?php $result->found_rows() ?>

...as it will try to acces a method, not a property !

Then, the only way to get the right result seems to be the use of a class function, like :

<?php
  $db
->query("select found_rows()");
 
$count=current(get_object_vars(current($db->result)));
?>

Of course, if somebody found an other way to solve it, like a special syntax (see the one used with curled arrays in a string), I'm really open to discuss.

Good luck,
Pascal
2005-10-13 10:21:48
http://php5.kiev.ua/manual/ru/ref.classobj.html
To access an object member with an illegal character in the name, use this syntax:

$obj->{'illegal-property:name()'}

This is particularly relevant with the dynamically-generated classes used by, for instance, database objects and the SoapClient class.
2007-12-20 09:02:18
http://php5.kiev.ua/manual/ru/ref.classobj.html
Автор:
We have an array with many objects in a style like

<?php

$step 
= new StepModel(1); // if the StepModel id is "1"
$demand $step->getDemand(); // returns DemandModel
$step2 $demand->getCustomer(); // returns StepModel
$demand2 $step2->getDemand(); // returns DemandModel

// [ ... ]

?>

$step and $step2 can be the same objects. So we have an recursive array. Now we need to know if $step == $step2 or $step === $step2. In other words: We need to know the php internal resource ids.

Because there is no function in php api, we made the following function.

Be careful: In our case, all objects have as first attribute ["id":protected]. If your objects are different from this, you need to edit $pattern.

Warning: function is very slow and should only be called if it's necessary for debugging reasons:

<?php

/**
 * returns resource- and object-ids of all objects in an array
 * 
 * @param array $array
 * @return array
 */
function getObjectInformation(Array $array)
{
   
// start output-buffering
   
ob_start();
   
   
// create an var_dump of $array
   
var_dump($array);
   
   
// save the dump in var $dump
   
$dump ob_get_contents();
   
   
// clean the output-buffer
   
ob_end_clean();
   
   
// delete white-spaces
   
$dump str_replace(' '''$dump);
   
   
// define the regex-pattern
    // in our case, all objects look like this:
    //
    // object(ClassName)#1(1){
    // ["id":protected]=>
    // string(1)"1"
   
$pattern  '/object\(([a-zA-Z0-9]+)\)#([0-9]+)\([0-9]+\){\\n';
   
$pattern .= '\["id":protected\]=>\\n';
   
$pattern .= 'string\([0-9]+\)"([v]?[0-9]+)"/im';
   
   
// search for all matches
   
preg_match_all($pattern$dump$regs);
   
   
// sort all mathes by class name, object id and then resource id
   
array_multisort($regs[1], SORT_ASCSORT_STRING,
                   
$regs[3], SORT_ASCSORT_NUMERIC,
                   
$regs[2], SORT_ASCSORT_NUMERIC);
   
   
// cache the last match
   
$lastMatch = array();
   
   
// the return value
   
$return = array();
   
   
// loop through the matches
   
for ($i 0$i sizeof($regs[0]); $i ++) {
       
       
// check if the current match was not visited before
       
if (== sizeof($lastMatch) ||
           
$regs[1][$i] != $lastMatch[1] ||
           
$regs[2][$i] != $lastMatch[2] ||
           
$regs[3][$i] != $lastMatch[3]) {
           
           
// save the match in return value
           
array_push($return, array($regs[1][$i],
                                     
$regs[2][$i],
                                     
$regs[3][$i]));
        }
       
       
// save match in last match cache
       
$lastMatch[1] = $regs[1][$i];
       
$lastMatch[2] = $regs[2][$i];
       
$lastMatch[3] = $regs[3][$i];
    }
   
   
// return all matches
   
return $return;
}

?>

I know, it's not that elegant but I hope it's useful for a few people.
2010-07-01 07:04:04
http://php5.kiev.ua/manual/ru/ref.classobj.html
Автор:
A small function that allows finding all references to the object. Written in 3 minutes and may be buggy (for ex pass object as reference in some places?)

<?php
function find_ref_obj($object$obj$path) {
    if (
in_array($obj,$GLOBALS['__REF_CHECKED'],true))
        return 
false;
   
$GLOBALS['__REF_CHECKED'][]=$obj;
   
$r = array();
    foreach ((array)
$obj as $k => $v) {
        if (
$v === $object)
           
$r[] = $path "->$k";
        if (
is_object($v)) {
           
$t find_ref_obj($object,$v,$path "->$k");
            if (
$t!==false
               
$r=array_merge($r,$t);
        }
        else if (
is_array($v)) {
           
$t find_ref_arr($object,$v,$path "->$k");
            if (
$t!==false
               
$r=array_merge($r,$t);
        }
    }
    if (empty(
$r))
        return 
false;
    else
        return 
$r;
}
function 
find_ref_arr($object$arr$path) {
    if (
in_array($arr,$GLOBALS['__REF_CHECKED'],true))
        return 
false;   
   
$GLOBALS['__REF_CHECKED'][]=$arr;
   
$r = array();
    foreach (
$arr as $k => $v) {
        if (
$v === $object)
           
$r[] = $path "['$k']";
        if (
is_object($v)) {
           
$t find_ref_obj($object,$v,$path "['$k']");
            if (
$t!==false
               
$r=array_merge($r,$t);
        }
        else if (
is_array($v)) {
           
$t find_ref_arr($object,$v,$path "['$k']");
            if (
$t!==false
               
$r=array_merge($r,$t);
        }
    }
    if (empty(
$r))
        return 
false;
    else
        return 
$r;
}
function 
find_references($object) {
   
$r = array();
   
$GLOBALS['__REF_CHECKED']=array();
    foreach (
$GLOBALS as $n => $v
    if (
$n!='__REF_CHECKED')
    if (
$n!='GLOBALS') {
        if (
$v === $object)
           
$r[]=$n;
        if (
is_object($v)) {
           
$t find_ref_obj($object,$v,$n);
            if (
$t!==false
               
$r=array_merge($r,$t);
        }
        else if (
is_array($v)) {
           
$t find_ref_arr($object,$v,$n);
            if (
$t!==false
               
$r=array_merge($r,$t);
        }
    }   
    unset(
$GLOBALS['__REF_CHECKED']);
    return 
$r;
}

function 
find_refs($object) {
    return 
implode(', ',find_references($object));
}
?>
2011-01-05 13:40:05
http://php5.kiev.ua/manual/ru/ref.classobj.html

    Поддержать сайт на родительском проекте КГБ