Доступ к нестатистическому свойству из статического метода
class database{
protected $db;
protected function connect(){
$this->db = new mysqli( /* DB info */ ); // Connecting to a database
}
}
class example extends database{
public function __construct(){
$this->connect();
}
public static function doQuery(){
$query = $this->db->query("theQuery"); // Not working.
$query = self::$db->query("theQuery"); // Not working.
$query = parent::$db->query("theQuery"); // Also not working.
}
}
Я хочу сделать что-то подобное, но я не могу найти способ, который работает, свойство должно статично...
Ответы
Ответ 1
Вы можете получить доступ, создав экземпляр нового объекта ($self = new static;
). Пример кода:
class Database{
protected $db;
protected function connect(){
$this->db = new mysqli( /* DB info */ ); // Connecting to a database
}
}
class Example extends Database{
public function __construct(){
$this->connect();
}
public static function doQuery(){
$self = new static; //OBJECT INSTANTIATION
$query = $self->db->query("theQuery"); // working.
}
}
Это то же самое, что и вызов $self = new Example;
но более программно, если имя класса когда-либо изменяется, оно не нуждается в обновлении.
Ответ 2
Вы не можете получить доступ к нестационарным свойствам из статических методов. Нестатические свойства относятся только к экземпляру объектов, где каждый экземпляр объекта имеет отдельное значение свойства.
Я проиллюстрирую на примере этот код не работает:
class Example {
public $a;
public __construct($a) {
$this->a = $a;
}
public static getA() {
return $this->a;
}
}
$first = new Example(3);
$second = new Example(4);
// is $value equal to 3 or 4?
$value = Example::getA();
Ответ 3
as marko said Вы не можете получить доступ к нестационарным свойствам из статических методов.
если возможно, измените свое свойство на статичное, а затем ваш код будет работать.
Я сделал что-то вроде этого.
class Member_DashBoard extends Page {
public static $lapsed_id = 4; //Membership lapsed status id
//calling static function by passing static property
$status_custom = self::getMembershipStatusLapsed(self::$lapsed_id);//
$status_custom_id = $status_custom['id'];
public static function getMembershipStatusLapsed($membershipStatusId) {
$statusDetails = array();
$membershipStatus = new Core_MembershipStatus();
$membershipStatus->id = $membershipStatusId;
if ($membershipStatus->find(TRUE)) {
Core_DAO::storeValues($membershipStatus, $statusDetails);
}
return $statusDetails;
}
}
надеюсь, что это кому-то поможет:)
- веселит
Ответ 4
Похожие сообщения здесь
Единственным способом вызова нестатического метода из статического метода является наличие экземпляра класса, содержащего нестатический метод. По определению, нестатический метод - это тот, который называется ON экземпляром некоторого класса, тогда как статический метод принадлежит самому классу.
Ответ 5
Лучше всего определять спецификации для объекта при его создании, и похоже, что ваша спецификация объекта не соответствует выбранному шаблону.
Как правило, вы должны спросить себя: "Мне нужен только один экземпляр объекта (статический) или более одного?"
Для этого конкретного экземпляра (подключение к базе данных и запрос к нему) использование объекта-объекта для объекта базы данных нецелесообразно, если вам не нужно устанавливать несколько подключений к базе данных /s.
Таким образом, у вас есть прецедент для объекта instanced vs static. Несколько одновременных подключений могут перегружать базу данных в зависимости от конфигурации и количества раз, когда соединение создается за одно исполнение.
Таким образом, имея в виду, существует несколько шаблонов проектирования ООП для PHP, доступных для поддержки архитектуры объекта/с. См. http://www.slideshare.net/RobertGonzalez/object-oriented-design-patterns-for-php-presentation для хорошей ходьбы от более распространенных шаблонов.
Для рабочего примера http://ideone.com/6qxvqx
Примечание Я переименовал mysqli в mysqli2 и создал поддельный класс для обработки запроса и добавил отслеживание к созданию соединения и объекта.
<?php
interface iDatabase
{
static public function execute();
public function instantiatedExecute();
}
abstract class database implements iDatabase
{
protected static $conn;
/**
* create an instance of database that uses the same connection across all instances
*/
final public function __construct()
{
self::connect();
}
/**
* Connect to a database if not already connected
*/
final protected static function connect()
{
if (null === self::$conn || false === (self::$conn instanceof mysqli)) {
self::$conn = new mysqli( /* DB info */ );
//add error checking here...
}
return self::$conn;
}
/**
* query database connection
*/
final public function query($query)
{
return self::doQuery($query);
}
/**
* static query database connection
*/
final public static function doQuery($query)
{
//sanitize query here if desired
return self::connect()->query($query);
}
}
class example extends database
{
/**
* example specific static execution
*/
public static function execute($query)
{
self::doQuery($query);
}
/**
* example specific non-static execution
*/
public function instantiatedExecute($query)
{
$this->query($query);
}
}
Ответ 6
я попробовал этот код, и он прекрасно работает:
class Router{
public function route($url){
var_dump($url);
}
}
используя этот метод вне класса, даже вне класса:
require_once('Router.php');
Router::route('/test/test');
так что можно получить доступ к публичным методам в статическом режиме
Ответ 7
Вы можете получить доступ к закрытому или защищенному свойству из статического метода.
class foo {
private $x;
static public function create()
{
$obj = new self();
$obj->x = 22;
return $obj;
}
}
$y = foo::create();
var_dump($y);
// object(foo)[1]
// private 'x' => int 22
// ----------------------
// this could just as easily be a normal method $bar->modify();
class bar {
private $x;
static public function modify(bar $bar)
{
$bar->x = 23;
}
}
$bar = new bar();
bar::modify($bar);
var_dump($bar);
// object(bar)[2]
// private 'x' => int 23