Php глобальный объект класса

Установить объект PHP глобальным?

Я только начал переводить свой проект из mysql в PDO. В моем проекте новый объект PDO создается более или менее правильно в начале программы.

$dbh_pdo = new PDO("mysql:host=$db_url;dbname=$db_database_name", $db_user, $db_password); 

Теперь я хотел бы использовать этот обработчик (это правильное имя?) В некоторых функциях и классах. Есть ли способ сделать объекты глобальными, как переменные, или я пытаюсь сделать что-то невыразимо глупо, потому что я не мог найти ничего при поиске в Интернете …

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

$pdo = new PDO('something'); function foo() < global $pdo; $pdo->prepare('. '); > 

Вы также можете проверить шаблон Singleton, который в основном представляет собой глобальный OO-стиль.

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

Я не знаю, как выглядит ваше приложение, но скажите, что вы делали это:

class TableCreator < public function createFromId($id) < global $pdo; $stmt = $pdo->prepare('SELECT * FROM mytable WHERE $stmt->execute(array($id)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as $row) < // do stuff >> > 

Вы должны сделать это вместо этого:

class TableCreator < protected $pdo; public function __construct(PDO $pdo) < $this->pdo = $pdo; > public function createFromId($id) < $stmt = $this->pdo->prepare('SELECT * FROM mytable WHERE $stmt->execute(array($id)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as $row) < // do stuff >> > 

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

Читайте также:  Аллен вайк javascript справочник

Вы будете использовать $GLOBALS[‘dbh_pdo’] вместо $dbh_pdo внутри любых функций. Или вы можете использовать ключевое слово global и использовать $dbh_pdo (то есть global $dbh_pdo ).

Вы также можете попробовать использовать Singleton, чтобы передать вам объект PDO. Таким образом, у вас будет только один объект PDO (и одно соединение с базой данных) в любом запросе, который сохраняет ресурсы памяти / сервера.

Источник

Глобальные объекты в PHP

global stars

В сообщении пойдет речь о фундаментальном в программировании — глобальных объектах. Я бы сказал, это научный вопрос, который хотелось бы обсудить. Итак, чтобы не «отстрелить себе ноги», программисты не программируют в глобальной области. Ок, все понятно и предельно просто, остановимся на этом? Не в этом материале. Как известно любое действие вызывает цепь событий и логических следствий.

Во первых, зачем создавать догму, которую можно не создавать? Вместо нее, давайте создадим функцию stop_globals(), например для языка PHP. Фреймворк, вначале выполнения своего кода, может ее выполнить, а дальнейшие попытки работы с глобальной областью, будут вызывать ошибки PHP. Хорошо ли данное решение?

Это еще далеко не все, что можно было бы обсудить.

Главная причина существования вышеуказанной догмы в том, что имеется возможность случайно затереть значения глобальных переменных, а это, в свою очередь, может привести, в том числе к трудно локализующимся ошибкам в программе. А если иметь возможность пользоваться глобальными переменными на чтение, но не на запись?

Давайте обратим внимание на окружающую нас Вселенную. В ней существуют глобальные объекты: пространство, время, материя, энергия, возможно темная материя и энергия. Подобным образом, исходя из моего опыта в веб-программировании, есть ряд объектов, для которых неудобно использовать Dependency Injection и такие объекты по своей сути, есть глобальные. Это объект связи с базой данных, объект `USER` и другие. Для работы с такими объектами, в PHP, можно было бы ввести функцию super(‘sky’, ‘user’), которая делала бы переменные $sky и $user суперглобальными, подобно как $_GET или $_POST.

Такое решение не хуже традиционной догмы «в глобальной области программировать нельзя», так как, запись данных в такие переменные сразу обнаружится и PHP выдаст ошибку, а преимущество в следующем:

  1. Концептуально глобальные объекты остаются глобальными, программа выглядит проще
  2. Такой подход более производителен. Намного быстрее обратиться к переменной напрямую, чем предварительно передавать ее значение через стек. Имеется ввиду, стек процессора, который используется компиляторами для передачи параметров функций. Так или иначе реализация паттерна DI, имеет накладные расходы на используемые ресурсы
  1. Поддерживаете ли вы введение экспериментальных функций super() и stop_globals()?
  2. Что думаете о вышеописанной идее в целом?

В заключении, хотел бы отметить свое наблюдение в отношении laravel и вреде паттернов программирования. Как известно laravel называют «кладязем антипаттернов». Считаю именно этот факт, а также свободное мышление его автора, позволило этому проекту стать столь популярным, каким он есть. Паттерны хороши для общения программистов, чтобы указать на некоторую программную сущность. Но они и вредят, путая программистов, не позволяя делать программы эффективными. Давайте делать программирование проще.

Источник

Глобальный объект

Добрый день.
Подскажите, как надо объявить класс data, так, что бы потом в начале документа сделать $data = new data и чтоб этот объект был доступен в любом подключённом файле и вообще где угодно.
Т.е. сейчас если я делаю include после $data = new data, то в подключаемом файле $data уже не существует. Подскажите как сделать глобальную переменную, доступную отовсюду.

Глобальный массив сервер!
Доброго времени суток хотел поинтересоваться, вот есть глобальный масив сервер с него вынимаем.

Глобальный объект
Как сделать, чтобы я создал объект, и его видел весь файл? Суть в том, что в конструктор я хочу.

Глобальный объект
Как сделать такое: при запуске программы (т.е. появление Главной формы) я создаю объект (коллекция).

Глобальный объект
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data;.

class Data { static private $instance = null; static public function get() { if (self::$instance === null) { self::$instance = new Data(); } return self::$instance; } }

В нужном месте любого класса Data::get() и получите экземпляр (это не совсем, но Singleton-паттерн).

ЦитатаСообщение от sMockingbird Посмотреть сообщение

Т.е. сейчас если я делаю include после $data = new data, то в подключаемом файле $data уже не существует.

Существует. Но я думаю то, что Вы используете её в методе класса, а в методе её нет (у методов своя область видимости).

ЦитатаСообщение от Razip Посмотреть сообщение

мне необходимо ещё сделать метод set и устанавливать некоторые значения, которые запишу в этот объект.
Получив экземпляр, там будут ранее определённые значения?

Прошу прощения, если неясно выражаюсь, раньше с php постольку поскольку работал)

а что значит private и public?
своими словами, погуглил уже, но не уверен, что правильно понял.
Спасибо

ЦитатаСообщение от sMockingbird Посмотреть сообщение

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class Data { static private $instance = null; static public function get() { if (self::$instance === null) { self::$instance = new Data(); } return self::$instance; } public function set($name, $value) { $this->$name = $value; } }

ЦитатаСообщение от sMockingbird Посмотреть сообщение

а что значит private и public?
своими словами, погуглил уже, но не уверен, что правильно понял.
Спасибо

Private — означает то, что метод доступен исключительно из других методов того же класса:

1 2 3 4 5 6 7 8 9 10 11 12
class Data { public function getHome() { return 'В доме: ' . implode(', ', $this->getHumans()) . '.'; } private function getHumans() { return ['Вася', 'Маша', 'Марина', 'Джон', 'Леонардо']; } } $data = new Data(); print $data->getHome();

ЦитатаСообщение от Razip Посмотреть сообщение

class Data { * static private $instance = null; static public function get() { * * if (self::$instance === null) { * * * self::$instance = new Data(); * * } return self::$instance; * } }

Нет, это у вас еще не Singleton. Паттерн Singleton позволяет создание экземпляра класса только в одном месте кода.

Singleton будет выглядеть вот так:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class Data { private function __construct(){} // запрещает конструкцию new Data private function __clone(){} // запрещает конструкцию clone Data::get() private function __wakeup(){} // запрещает конструкцию unserialize(serialize(Data::get())), хотя я вообще __sleep бы запретил. static private $instance = null; static public function get() { if (self::$instance === null) { self::$instance = new Data(); } return self::$instance; } public function set($name, $value) { $this->$name = $value; } }

Источник

класс — мне нужен объект PHP в глобальной области видимости. Как мне это сделать, или есть лучший способ?

Я пытаюсь создать свое первое объектно-ориентированное веб-приложение и у меня возник вопрос о том, как глобально ссылаться на объект. Не уверен, если это необходимо или нет, но здесь немного фона. Приложение представляет собой одностраничное приложение.

Index.php создает новый экземпляр класса «Page». Этот экземпляр проверяет параметр url (page = . ), а затем проверяет наличие соответствующего класса содержимого и вызывает внутри него функцию. Если этот класс страницы не существует, он вызывает другой класс 404 и отображает его.

Каждый класс содержимого страницы расширен от класса BasePage. Так например index.php?page=Home будет работать так

+---------+ +----------+ | | creates instance of Page.php | | |index.php|----------------------------->| page.php | | | | | +---------+ +----------+ +----------+ | | / | base.php | / | | / "Page" loads the relevant class +----------+ / and calls a function within it home.php | |/_ extends base.php +----------+ | | | home.php | | | +----------+ 

Надеюсь, это имеет смысл до сих пор. Проблема, с которой я столкнулся сейчас, заключается в том, что мне нужен объект «Пользователь», который создается из экземпляра класса «Пользователь». На этот объект User будут ссылаться почти на каждой странице, Index.php, page.php и home.php. То, что происходило до сих пор, это то, что я создал экземпляры класса User в каждом другом классе. Это работает, но часто приводит к нескольким вызовам базы данных и созданию нескольких объектов пользователя. Я думаю, что лучшим подходом было бы сделать класс User одноэлементным классом, но где я могу создать этот одноэлементный объект. Если я создаю экземпляр в base.php, home.php имеет ссылку на него, а page.php и index.php — нет. Если я создаю экземпляр в index.php, ни одна другая страница не будет иметь к нему доступа, если я не передам его каждому классу — что становится грязным. (Я знаю, я пытался).

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

Кто-нибудь может дать совет? Как я должен создавать свой объект User?

Решение

Если вы решите попробовать и внедрить синглтон, это будет примером того, как гарантировать, что ваш пользователь всегда один и тот же:

class User < private static $instance = null; private $name; public function __construct($name) < $this->name = $name; > public static function get($name) < if (self::$instance === null) self::$instance = new self($name); return self::$instance; >public function sayHello() < echo 'Hello my name is '.$this->name; > > $user = User::get('Bob'); $user->sayHello(); // Hello my name is Bob 

Помните, что такие практики подвержены ошибкам, ярости и ненависти, смешивая статические классы и динамические экземпляры.

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

принцип такого контейнера состоит в том, чтобы определить ваши объекты, а затем извлечь их, сконструированные только те, которые необходимы. Скажем, вы используете прыщ:

$cnt = new Pimple(); $cnt['page'] = function($c) < // the class pimple passes the container itself to the functions you define return new page($c['session']); // defines the page key to return a new page >; $cnt['session'] = function() < return new session(); >; $page = $cnt['page']; // constructs the session because it is called to construct the page 

Другие решения

То, что вы ищете, это синглтон. Но шаблон Singleton считается ОЧЕНЬ плохой практикой, и его следует избегать любой ценой. Вы должны стараться избегать любого решения, которое требует от вас глобальных вещей.

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

Несколько небольших статей о том, почему синглтон плох:

Источник

Оцените статью