Разница между:: и → в PHP

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

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

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

class StaticDemo {  
    private static $static  
}

$staticDemo = new StaticDemo( );

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

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

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

Ответы

Ответ 1

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

Ответ 2

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

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

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

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

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

Ответ 3

В режиме 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.

Ответ 4

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

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

Я бы не сказал, что не используя статические вызовы, вы тоже плохой человек!

Ответ 5

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

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

Ответ 6

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

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), который является единственным объектом.

Ответ 7

:: используется для статических методов, которые вы вызываете, если у вас нет экземпляра объекта.

Ответ 8

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

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

class foo {
  public static $i = 0;

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

$a = new foo();
$b = new foo();
echo foo::$i;
// outputs 2

Ответ 9

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

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"

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

Ответ 10

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

Правильно.

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

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

Ответ 11

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

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

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

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

См. "Примечание... в документации...": 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

Ответ 12

Хорошо, что вы правы в использовании → и::. Но иногда это просто не делает смысл для создания объектов класса. Вот пример Сравнить

class Settings
{
    public static $setting1;
    public static $setting2;
    ... // lots of other vars and functions
}
if(Setting::$setting1)
    //do something

против

class Settings
{
    public $setting1;
    public $setting2;
    ... // lots of other vars and functions
}
$set = new Settings()
if($set->setting1)
    //do something

Как я уже сказал, не имеет смысла создавать экземпляры, поскольку всегда требуется только один. в этом случае статические подходят лучше. Оказывается, в сети мы в основном занимаемся таким случаем, если вы не имеете дело с реальными объектами, например. пользователей и т.д., следовательно, преобладание прежнего