Глобали неминучі.
Це давнє обговорення, але я все ж хотів би додати деякі думки, тому що я пропускаю їх у вищезгаданих відповідях. Ці відповіді спрощують те, що глобальний - це занадто багато, і представляють рішення, які зовсім не є вирішенням проблеми. Проблема полягає в тому, що є правильним способом боротьби із глобальною змінною та використанням ключового слова global? Для цього ми спочатку повинні вивчити та описати, що таке глобальний.
Погляньте на цей код Zend - і, будь ласка, зрозумійте, що я не припускаю, що Zend погано написаний:
class DecoratorPluginManager extends AbstractPluginManager
{
/**
* Default set of decorators
*
* @var array
*/
protected $invokableClasses = array(
'htmlcloud' => 'Zend\Tag\Cloud\Decorator\HtmlCloud',
'htmltag' => 'Zend\Tag\Cloud\Decorator\HtmlTag',
'tag' => 'Zend\Tag\Cloud\Decorator\HtmlTag',
);
Тут дуже багато невидимих залежностей. Ці константи - це фактично класи. Ви також можете побачити Requ_once на деяких сторінках цього фреймворку. Require_once - це глобальна залежність, отже, створюється зовнішня залежність. Це неминуче для рамки. Як можна створити такий клас, як DecoratorPluginManager, без багато зовнішнього коду, від якого це залежить? Він не може функціонувати без безлічі додатків. Використовуючи рамку Zend, ви коли-небудь змінювали реалізацію інтерфейсу? Насправді інтерфейс є глобальним.
Ще одне глобально використовуване додаток - Drupal. Вони дуже стурбовані правильним дизайном, але, як і будь-які великі рамки, у них багато зовнішніх залежностей. Погляньте на глобалістів на цій сторінці:
/**
* @file
* Initiates a browser-based installation of Drupal.
*/
/**
* Root directory of Drupal installation.
*/
define('DRUPAL_ROOT', getcwd());
/**
* Global flag to indicate that site is in installation mode.
*/
define('MAINTENANCE_MODE', 'install');
// Exit early if running an incompatible PHP version to avoid fatal errors.
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the <a href="http://drupal.org/requirements">system requirements</a> page for more information.';
exit;
}
// Start the installer.
require_once DRUPAL_ROOT . '/includes/install.core.inc';
install_drupal();
Ви коли-небудь писали переспрямування на сторінку входу? Це змінює глобальне значення. (Тоді ви не говорите "WTF", що я вважаю хорошою реакцією на погану документацію вашої заявки.) Проблема глобальних мереж полягає не в тому, що вони глобальні, вони вам потрібні для того, щоб мати змістовне застосування. Проблема полягає у складності загальної програми, яка може зробити її кошмаром. Сесії - глобальні, $ _POST - глобальний, DRUPAL_ROOT - глобальний, включаючи / install.core.inc '- глобальний, що не може змінюватися. Поза межами будь-якої функції є великий світ, який необхідний для того, щоб дозволити цій функції виконувати свою роботу.
Відповідь Гордона невірна, оскільки він завищує незалежність функції і називає функцію брехуном - це надто спрощує ситуацію. Функції не брешуть, і коли ви дивитесь на його приклад, функція розроблена неправильно - його приклад - помилка. (До речі, я погоджуюся з таким висновком, що слід роз'єднати код.) Відповідь обману насправді не є правильним визначенням ситуації. Функції завжди функціонують у більш широкому обсязі, і його приклад є занадто спрощеним. Всі ми погодимося з ним, що ця функція є абсолютно марною, оскільки вона повертає константу. Ця функція все одно погана конструкція. Якщо ви хочете показати, що практика погана, будь ласка, будьте відповідним прикладом. Перейменування змінних у всій програмі не є великою справою, маючи хороший IDE (або інструмент). Питання стосується сфери дії змінної, а не різниці в області застосування з функцією. Існує належний час, коли функція може виконувати свою роль у процесі (саме тому вона створюється в першу чергу), і в цей належний час може вплинути на функціонування програми в цілому, отже, також працює над глобальними змінними . Відповідь xzyfer - це твердження без аргументації. Глобали так само є в програмі, якщо у вас є процедурні функції або дизайн OOP. Наступні два способи зміни значення глобальної суті однакові: отже, також працює над глобальними змінними. Відповідь xzyfer - це твердження без аргументації. Глобали так само є в програмі, якщо у вас є процедурні функції або дизайн OOP. Наступні два способи зміни значення глобальної суті однакові: отже, також працює над глобальними змінними. Відповідь xzyfer - це твердження без аргументації. Глобали так само є в програмі, якщо у вас є процедурні функції або дизайн OOP. Наступні два способи зміни значення глобальної суті однакові:
function xzy($var){
global $z;
$z = $var;
}
function setZ($var){
$this->z = $var;
}
В обох випадках значення $ z змінюється в межах конкретної функції. В обох способах програмування ви можете внести ці зміни в купу інших місць коду. Можна сказати, що, використовуючи глобальний, ви можете зателефонувати в $ z і змінити там. Так, ти можеш. Але ти будеш? І коли це робиться в невідповідних місцях, чи не слід це називати клопом?
Bob Fanger коментує xzyfer.
Чи повинен тоді хтось просто використовувати щось, особливо ключове слово «глобальний»? Ні, але, як і будь-який тип дизайну, спробуйте проаналізувати, від чого це залежить і від чого залежить. Спробуйте дізнатися, коли вона змінюється і як вона змінюється. Зміна глобальних значень має відбуватися лише з тими змінними, які можуть змінюватися з кожним запитом / відповіддю. Тобто лише до тих змінних, які належать до функціонального потоку процесу, а не до його технічної реалізації. Перенаправлення URL-адреси на сторінку входу належить до функціонального потоку процесу, класу реалізації, який використовується для інтерфейсу технічної реалізації. Ви можете змінити останню під час різних версій програми, але не слід змінювати їх із кожним запитом / відповіддю.
Для подальшого розуміння, коли це проблема з глобалізацією та ключовим словом глобальний, а коли ні, я введу наступне речення, яке походить від Віма де Бі, коли він пише про блоги: "Особистий так, приватний ні". Коли функція змінює значення глобальної змінної заради власного функціонування, то я буду називати приватне використання глобальної змінної та помилку. Але коли зміна глобальної змінної робиться для належної обробки додатку в цілому, як перенаправлення користувача на сторінку входу, то, на мою думку, це можливо хороший дизайн, а не за визначенням поганий і, звичайно, не анти-візерунок.
Зрештою, на відповіді Гордона, deze та xzyfer: всі вони мають "приватний" (та помилки) як приклади. Ось чому вони проти використання глобалів. Я б теж зробив. Однак вони не мають «особистого так, приватних ні-прикладів», як я робив у цій відповіді кілька разів.