Разница между :: и -> в PHP - PullRequest
14 голосов
/ 10 мая 2010

Я всегда вижу, как люди в серьезных проектах используют :: везде, и -> только иногда в локальной среде.

Я использую только -> себя и никогда не оказываюсь в ситуациях, когда мне нужно статическое значение вне класса. Я плохой человек?

Как я понимаю, единственная ситуация, когда -> не работает, - это когда я пытаюсь выполнить следующее:

class StaticDemo {  
    private static $static  
}

$staticDemo = new StaticDemo( );

$staticDemo->static; // wrong  
$staticDemo::static; // right

Но я упускаю некоторую корректность программирования, когда я не вызываю простые публичные методы ::?

Или это просто для того, чтобы я мог вызывать метод без создания экземпляра?

Ответы [ 12 ]

12 голосов
/ 10 мая 2010

Двойное двоеточие используется, когда вы не создаете экземпляр класса

class StaticDemo {...};
StaticDemo::static

если вы создаете экземпляр, используйте ->

class StaticDemo {...};
$s = new StaticDemo();
$s->static;

Это объясняется далее на http://php.net/manual/en/language.oop5.patterns.php

7 голосов
/ 10 мая 2010

:: для ссылки на статические свойства или методы класса. -> для ссылки на свойства и методы экземпляра. Вы не упускаете ни одной правильности программирования, и если вы плохой человек, то это не из-за этого. Какой из них вы используете, зависит от цели вашего класса и от того, как он написан. Но также в PHP до недавнего времени не было пространств имен, поэтому многие люди инкапсулировали свой код в статические классы, чтобы эмулировать пространства имен, чтобы избежать конфликтов имен. Возможно, вы видите код, который это делает.

4 голосов
/ 10 мая 2010

Вы вызвали предупреждение о строгих стандартах в режиме E_STRICT. Вы плохой человек.

<?php

error_reporting(E_ALL | E_STRICT);

header('Content-type: text/plain');

class Foo {
    public $msg = "Hello, public.\n";
    public static $msgStatic = "Hello, static.\n";

    public function write() {
        echo "Hello, write.\n";
    }

    public static function writeStatic() {
        echo "Hello, writeStatic.\n";
    }
}

//echo Foo::$msg; // Fatal error: Access to undeclared static property: Foo::$msg
echo Foo::$msgStatic;
echo Foo::write(); // Strict Standards: Non-static method Foo::write() should not be called statically
echo Foo::writeStatic();

echo "------------------------\n";

$f = new Foo;
echo $f->msg;
echo $f->msgStatic; // Strict Standards: Accessing static property Foo::$msgStatic as non static
                    // Notice: Undefined property: Foo::$msgStatic
echo $f->write();
echo $f->writeStatic();

Выход:

Hello, static.

Strict Standards: Non-static method Foo::write() should not be called statically in /home/adam/public_html/2010/05/10/bad.php on line 22
Hello, write.
Hello, writeStatic.
------------------------
Hello, public.

Strict Standards: Accessing static property Foo::$msgStatic as non static in /home/adam/public_html/2010/05/10/bad.php on line 29

Notice: Undefined property: Foo::$msgStatic in /home/adam/public_html/2010/05/10/bad.php on line 29
Hello, write.
Hello, writeStatic.
3 голосов
/ 10 мая 2010

-> для экземпляра класса. :: это статический вызов.

:: используется в конструкторах наследования (дочерний элемент обращается к родительскому конструктору) и при обращении к статическому методу внутри другого метода.

Я бы не сказал, что использование статических звонков делает вас плохим человеком!

2 голосов
/ 11 мая 2010

Насколько я понимаю, статика распределяется между объектами одного типа:

class test{
    static function print_test(){
        print "hello!";
    }
}
$objectA = new test();
$objectB = new test();

Функция print_test будет «разделена» между двумя объектами. Но подвох в том, что функция print_test () не должна ссылаться на что-либо внутри класса! даже если PHP 5 принимает его.

Так как функция print_test в примере просто печатает "привет!" и ничего не ссылается внутри класса, зачем выделять для него память в $ objectA и $ objectB? Просто сделайте одну статическую функцию, и $ objectA и $ objectB должны автоматически указывать на нее.

Что ж, это теория, лежащая в основе этого в других языках, но поскольку php5 позволяет ссылаться на $ this в статической функции, я не верю, что это истинная статическая функция, поскольку она должна быть динамической, чтобы получить какие-либо свойства для ( $ this-> variable ) этот уникальный объект.

2 голосов
/ 10 мая 2010

Да, вы можете вызвать метод или получить доступ к значению, не создавая экземпляр.

Было бы полезно, например, если у вас есть значение, которое используют все экземпляры класса. Предположим, что это значение необходимо инициализировать в начале вашего приложения. Вы можете использовать что-то вроде StaticDemo::static = 42; для инициализации, и тогда все экземпляры вашего класса смогут получить к нему доступ.

1 голос
/ 10 мая 2010

Как говорили другие,

  • :: 'double двоеточие' для ссылки на статическое свойство или метод.
  • -> 'стрелка тире' для ссылки на свойство или метод экземпляра класса.

Но также стоит отметить, что

  • :: часто используется в текстах как сокращение для ссылки на свойство или метод, принадлежащий определенному классу (будь то статический или экземпляр).

См. «Примечание ... в документации ...»: http://books.google.co.uk/books?id=qVLjFk_4zVYC&lpg=PA66&dq=php%205%20objects&pg=PA46#v=onepage&q=php%205%20objects&f=false

1 голос
/ 10 мая 2010

Или это просто так, что я могу вызывать метод, не создавая экземпляр?

Correct.

:: (операторы разрешения контекста) используются при вызове статических методов / членов. Вам не нужно создавать экземпляр для этого (как вы это делали в своем примере).

Использование -> и :: в правильном контексте является ключом к правильности объектно-ориентированного программирования. Вы должны создавать статические переменные / методы только тогда, когда они применяются к классу в целом, а не только к конкретному экземпляру (объекту) класса.

1 голос
/ 10 мая 2010

Используйте «->» в контексте объекта и «::» для прямого доступа к классу. В вашем примере это будет:

class StaticDemo {
    public static $staticVar = 'blabla';
    public $normalVar = 'foobar';
}

$foo = new StaticDemo();
echo $foo->normalVar; //object context, echoes "foobar"
echo StaticDemo::staticVar; //class or "static" context, echoes "blabla"

Прочитайте это для подробной информации.

1 голос
/ 10 мая 2010

Статические методы и свойства не зависят от конкретного экземпляра класса. К ним нужно обращаться, используя двойные двоеточия (: :). Нестатические методы и свойства должны быть доступны с помощью ->

Это позволяет вам делать довольно интересные вещи. Тривиальным примером является счетчик, который отслеживает количество экземпляров класса существует:

class foo {
  public static $i = 0;

  public function __construct() {
    self::$i++;
  }
}

$a = new foo();
$b = new foo();
echo foo::$i;
// outputs 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...