производительность загрузки классов php и использование 'extends' - PullRequest
5 голосов
/ 31 июля 2009

У меня есть страница includes.php, которую я загружаю в начале каждой страницы моего сайта. По мере того, как я разрабатываю сайт, количество классов, которые я использую, растет. В итоге я получаю что-то вроде этого:

$db = new DB($config);
$login = new Login($db, $config);
$form = new Form($db, $config);

И этот список можно продолжать и продолжать. У меня есть два вопроса об этой практике:

Во-первых, учитывая, что я не могу использовать класс на определенной странице (у меня может не быть формы $ на каждой странице), насколько это действительно важно, с точки зрения производительности, загружать этот класс каждый раз, когда страница загружена?

Во-вторых, вы, возможно, заметили, что я передаю экземпляр класса $ db всем другим классам, а также переменную $ config. В коде php каждого класса я делаю что-то вроде этого:

public $db;
public $config;

public function __construct($db, $config, $smarty){
    $this->db = $db;
    $this->config = $config;
}

затем в методах класса я обращаюсь к базе данных и файлам конфигурации с помощью 'this' следующим образом:

public function myfunction(){
  $this->db;
  $this->config;
}

Когда мне следует использовать 'extends' вместо передачи $ db классу, предполагая, что каждый класс использует db? Вредит ли передача $ db каждому классу с точки зрения производительности?

Спасибо!

Ответы [ 5 ]

7 голосов
/ 31 июля 2009

Когда я должен использовать «расширяет», а чем передать $ db классу, при условии, что каждый класс использует БД?

Когда это имеет смысл - и только тогда, когда это имеет смысл!

У вас есть по крайней мере две вещи для рассмотрения:

  • "class A extends B" Вид средств "class A **is a** B"
    • более четко, Car - это MotorVehicule; MotorVehicule представляет собой Vehicule; Bus - это MotorVehicule; Велосипед это Vehicule
    • однако Ball не является Vehicule
    • В вашем случае Form определенно не DataBase! Также не является Login
  • В PHP класс может только extend один класс
    • Вы не можете иметь что-то одновременно Vehicule и Animal
    • Но Car - это MotorVehicule, что само по себе является Vehicule : -)

В случае объекта базы данных (в вашем случае это скорее соединение с БД) , большинство ваших классов сами не будут "подключаться к базе данных". Поэтому они не должны расширять этот класс.

Однако они используют соединение с БД (Form " имеет соединение с БД ") ; поэтому они должны иметь свойство, представляющее это соединение с БД. Это то, что вы делаете.


Вместо передачи $db каждому конструктору, вы можете использовать

  • либо Singleton шаблон проектирования
  • или шаблон проектирования реестра
  • или какая-то глобальная переменная, но это почти то же самое ... просто хуже (не ООП и все такое) !

Но передача объекта $db отлично подходит для модульного тестирования, макетов объектов и всего такого ...
Я думаю, это можно рассматривать как шаблон проектирования Dependancy Injection, кстати (не уверен, но выглядит так)


О загрузке большого количества классов, другие люди дали ответы:

  • Используйте автозагрузку, если можете
  • Используйте кэш кода операции, например APC, если можете

Оба эти отличных предложения, которые вам следует принять во внимание ; -)


И последнее:

Действительно ли передача $ db каждому классу больно каким-либо образом с точки зрения производительности?

Может быть, это маленький бит; но, честно говоря, если только вы не гуглили и у вас миллионы пользователей ... кого это волнует?

Если вы выполняете несколько запросов к БД, на это потребуется МНОГО времени, по сравнению с передачей еще одного параметра даже дюжине методов!
Итак, небольшим количеством времени, используемым для прохождения параметров, можно пренебречь : -)

4 голосов
/ 31 июля 2009

Вы пробовали что-то подобное?

function __autoload($class_name) {
 require_once("includes/php/class." . $class_name . ".php");
 }

Таким образом, он загружает имя класса только тогда, когда встречается имя класса. (Измените путь в соответствии с вашими php-классами ... мой похож на class.Object.php с именем класса "Object").

1 голос
/ 31 июля 2009

Я не уверен, как именно вы хотите использовать наследование ('extends') здесь. Вы можете использовать его для определения двух полей $db и $config, но в противном случае это не сильно изменится.

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

В зависимости от вашего дизайна, вы можете сделать глобальный $config. Есть ли ситуация, когда одновременно активна более 1 конфигурации? Однако, вероятно, было бы не очень хорошей идеей вводить глобальную переменную $db. Вполне возможно, что вам может понадобиться более одного подключения к базе данных одновременно, например.

1 голос
/ 31 июля 2009

Если загрузка и синтаксический анализ файлов сценариев становятся узким местом, вы можете использовать кэш байт-кода, например apc , чтобы ускорить эту часть жизненного цикла.

1 голос
/ 31 июля 2009

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

Если $db передается как ссылка, это не должно влиять на производительность. (Я не очень разбираюсь в PHP5, но в PHP4 была концепция ссылки с модификатором '&'.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...