PHP Velho Oeste 2024

class

Класс - это совокупность переменных и функций, работающих с этими переменными. Переменные определяются при помощи ключевого слова var, а функции при помощи ключевого слова function. Класс определяется при помощи следующего синтаксиса:

<?php
class Cart {
    var 
$items;  // Продукты в нашей корзине

    // Добавляет $num товаров $artnr в корзину

    
function add_item($artnr$num) {
        
$this->items[$artnr] += $num;
    }

    
// Убирает $num товаров $artnr в корзину

    
function remove_item($artnr$num) {
        if (
$this->items[$artnr] > $num) {
            
$this->items[$artnr] -= $num;
            return 
true;
        } elseif (
$this->items[$artnr] == $num) {
            unset(
$this->items[$artnr]);
            return 
true;
        } else {
            return 
false;
        }
    }
}
?>

Здесь определён класс с именем Cart, который состоит из ассоциативного массива товаров в корзине и двух функций для добавления и удаления продуктов из этой корзины.

Внимание

Вы НЕ можете разрывать определение класса в несколько разных файлов. Вы также НЕ можете разрывать определение класса в различные блоки PHP, кроме случая, если разрыв происходит внутри объявления метода. Следующий код не будет работать:

<?php
class test {
?>
<?php
    
function test() {
        print 
'OK';
    }
}
?>

Однако, так делать можно:

<?php
class test {
    function 
test() {
        
?>
        <?php
        
print 'OK';
    }
}
?>

Следующие предостерегающие замечания справедливы для PHP 4.

Предостережение

Имя stdClass зарезервировано для использования внутри Zend. Вы не можете определить свой класс с именем stdClass в PHP.

Предостережение

Функции __sleep и __wakeup являются волшебными в классах PHP. Вы не можете создать функции с такими именами в ваших классах, если вы не хотите использовать волшебную функциональность, связанную с ними. Смотрите больше информации ниже.

Предостережение

В PHP зарезервированы имена функций, начинающихся с __ как волшебные. Рекомендуется не использовать имена функций, начинающиеся с __ в PHP, если только вы не хотите использовать какую-либо документированную волшебную функциональность.

В PHP 4 допускаются только постоянные инициализаторы для переменных var. Чтобы инициализировать переменные не постоянными значениями, вам нужно использовать инициализирующую функцию, которая вызывается автоматически когда объект конструируется из класса. Такая функция называется конструктором (смотрите ниже).

<?php
class Cart {
    
/* Ничего из этого не будет работать в PHP 4. */
    
var $todays_date date("Y-m-d");
    var 
$name $firstname;
    var 
$owner 'Фред ' 'Джонс';
    
/* Хотя присвоение массивов с постоянными значениями будет работать. */
    
var $items = array("VCR""TV");
}

/* Вот как нужно делать. */
class Cart {
    var 
$todays_date;
    var 
$name;
    var 
$owner;
    var 
$items = array("VCR""TV");

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

Классы - это типы, таким образом, они являются наметками для переменных. Вы можете создать переменную желаемого типа при помощи оператора new.

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

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

В листинге выше создаётся два объекта, $cart и $another_cart, оба класса Cart. Функция add_idem() объекта $cart вызывается для того, чтобы добавить 1 товар артикула 10 к объекту $cart. 3 товара артикула 0815 будут добавлены к объекту $another_cart.

Оба объекта, $cart и $another_cart, имеют функции add_item(), remove_item() и переменную items. Однако это разные функции и переменные. Вы можете представлять себе объект как нечто похожее на каталоги в файловой системе. В файловой системе вы можете иметь два разных файла README.TXT, если они находятся в разных каталогах. Так же, как и с каталогами, где вы должны ввести полный путь к файлу, чтобы обратиться к файлу из каталога верхнего уровня, вы должны указать полное имя функции, которую вы хотите вызвать: в нотации PHP, каталог верхнего уровня называется "Глобальное пространство имен", а разделителем пути является символ ->. Таким образом, названия $cart->items и $another_cart->items обозначают две разных переменных. Заметьте, что переменная называется $cart->items, а не $cart->$items, таким образом, название переменной в PHP имеет только один знак доллара ($).

<?php
// Правильно, один символ $
$cart->items = array("10" => 1); 

// Неправильно, $cart->$items - это $cart->"", так как в глобальном пространстве имен
// переменная $item не задана
$cart->$items = array("10" => 1);

// Сработает, но лучше так не делать.
// $cart->$myvar превратится в $cart->items
$myvar 'items';
$cart->$myvar = array("10" => 1);  
?>

При определении класса, вы не знаете, под каким именем объект будет доступен в вашей программе: во время описания класса Cart было неизвестно, как позднее будет назван объект: $cart, $another_cart или как-нибудь ещё. Таким образом, вы не можете написать $cart->items в классе Cart. Вместо этого, для того, чтобы иметь возможность доступа к своим собственным переменным и функциям внутри класса, можно использовать псевдо-переменную $this которая может быть прочитана как 'мой собственный' или 'текущий объект'. Таким образом, '$this->items[$artnr] += $num' может быть прочитано как 'добавить $num к счётчику $artnr моего собственного массива продуктов' или 'добавить $num к счётчику $artnr массива продуктов текущего объекта'.

Замечание:

Псевдо-переменная $this обычно не определена, если метод, который обращается к ней, вызывается статически. Однако, это не строгое правило: переменная $this определена, если метод вызывается статически из другого объекта. В этом случае значение переменной $this будет указывать на вызывающий объект. Это проиллюстрировано в следующем примере:

<?php
class A
{
    function 
foo()
    {
        if (isset(
$this)) {
            echo 
'$this определена (';
            echo 
get_class($this);
            echo 
")\n";
        } else {
            echo 
"\$this не определена.\n";
        }
    }
}

class 
B
{
    function 
bar()
    {
        
A::foo();
    }
}

$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>

Результат выполнения данного примера:

$this определена (a)
$this не определена.
$this определена (b)
$this не определена.

Замечание:

Есть несколько прикольных функций для работы с классами и объектами. Если захотите из изучить, смотрите раздел Функции классов и объектов.

add a note add a note

User Contributed Notes 5 notes

up
7
ender911t at gmail dot com
8 years ago
Overrides in child are called when calling a function from the parent

<?PHP
class Par
{
   var
$test;
   function
__construct($in)
   {
     
$this->test = $in;
   }

   function
getTest()
   {
      return
$this->test;
   }

   function
runTest()
   {
      return
$this->getTest();
   }
}

class
Chi extends Par
{
   var
$i;
   function
__construct($in)
   {
     
$this->i = $in;
     
parent::__construct($in."X");
   }

   function
getTest()
   {
      return
$this->i;
   }

   function
runParentTestA()
   {
      return
parent::runTest();
   }

   function
runParentTestB()
   {
      return
parent::getTest();
   }
}

$p = new Par("par");
$c = new Chi("chi");

echo
$p->runTest()." == par";
echo
$c->runTest()." == chi";
echo
$c->runParentTestA()." == chi";
echo
$c->runParentTestB()." == chiX";
?>
up
5
anthonymccuen at yahoo dot com
11 years ago
You can also use "var" to declare multiple public instance variables like in C:

int main(int *argc, const char *argv[]) {
    int a, b, c, d, e, f;
   
    a = 50;
    // blah blah blah code here
    // ...
   
    return 0;
}

Same as PHP:

<?php
class MyClass {
    var
$myvar, $anotherVar, $something, $str;
}
?>
up
1
masonswolf at gmail dot com
11 years ago
You can invoke a class above its definitions in some cases, but there are very important exceptions to this behavior. If your class extends another class, and the interpreter doesn't see the extended class first, then it won't be added to the symbol table until the code has stepped through it in runtime. As a result, if you try to invoke it above the definition, you'll get a "class not found" fatal error.

And those suck.

So, to provide an example, the following will output a fatal error
<?php
Bar
::bar();
exit;

class
Bar extends Foo { } //will fatal because Foo not seen yet

class Foo {
    static function
bar() { echo 'yep, this is Foo::bar'; }
}
?>

However, THIS code will work just fine:
<?php
Bar
::bar();
exit;

class
Foo {
    static function
bar() { echo 'yep, this is Foo::bar'; }
}

class
Bar extends Foo { } //will work because Foo came first
?>

Notice that if you include a file containing the class you will extend, and then extend the class in the same file as its invocation, you can also get the class not found fatal. This happens even if the 'include' call happens before the child class's definition.

Eg. the following will also output a fatal error
<?php
include_once('file_with_foo.php');

Bar::bar();
exit;

class
Bar extends Foo { }
?>

Hope that clarifies things.
up
-9
pov at fingerprint.fr
12 years ago
I just discovered a behaviour that has to be mentioned.

Let's consider the following file

<?php
Foo
::bar();
exit;

class
Foo {
  function
bar() { echo 'yep, this is Foo::bar'; }
}
?>

You may expect :
- an error on the Foo::bar call, because the class is not defined
- removing the code after the exit without side-effect

But it won't, and it will output the string !
It seems every class definition is executed at parse-time.

But without errors; if your file is
<?php
Foo
::bar();
exit;

class
Foo {
  function
bar() { echo 'yep, this is Foo::bar'; }
}
class
Foo {
  function
bar() { echo 'yep, this is another Foo::bar'; }
}
?>
it will still output the first string, not doing any "Already exiting class" error !

So if you intend preventing a double include by doing in an included file :
<?php
if (class_exists('Foo')) { return; }

class
Foo {
  static function
register() { ... }
}
Foo::register();
?>
the Foo::register method won't be called !

Very strange development choice; I suppose it is due to ascending compatibility.
Hope it can help...
up
-10
boukeversteegh at gmail dot com
13 years ago
You can also instantiate objects using variables containing the name of the class:

<?php

$type
= 'Foo';
$foo   = new $type();

print_r( $foo );
/* Prints:
Foo Object
(
)
*/
?>

The following works as well:
<?php

$somefoo   
= new Foo();
$anotherfoo = new $somefoo();

# so you don't have to do:
$anotherfoo = new get_class( $somefoo)();
?>
To Top