It’s not actually an Apache related question. Nor even a PHP related one.
To understand this error you have to distinguish a path on the virtual server from a path in the filesystem.
require
operator works with files. But a path like this
/common/configs/config_templates.inc.php
only exists on the virtual HTTP server, while there is no such path in the filesystem. The correct filesystem path would be
/home/viapics1/public_html/common/configs/config_templates.inc.php
where
/home/viapics1/public_html
part is called the Document root and it connects the virtual world with the real one. Luckily, web-servers usually have the document root in a configuration variable that they share with PHP. So if you change your code to something like this
require_once $_SERVER['DOCUMENT_ROOT'].'/common/configs/config_templates.inc.php';
it will work from any file placed in any directory!
Update: eventually I wrote an article that explains the difference between relative and absolute paths, in the file system and on the web server, which explains the matter in detail, and contains some practical solutions. Like, such a handy variable doesn’t exist when you run your script from a command line. In this case a technique called «a single entry point» is to the rescue. You may refer to the article above for the details as well.
За последние 24 часа нас посетили 8790 программистов и 854 робота. Сейчас ищет 381 программист …
-
- С нами с:
- 16 июл 2013
- Сообщения:
- 11
- Симпатии:
- 0
В php я новичок и поэтому не особо понимаю в чем моя ошибка
Поставил денвер с php 5.3 и пакет расширений
Накатил DLE 9.8
И всё работает, но мне нужно влепить еще одну маленькую cms модулем
Сам DLE и cms по отдельности работают, но стоит мне впилить эту cms в окно {content} сайта, как всё крашится с ошибкойFatal error: require_once(): Failed opening required ‘./smarty/libs/Smarty.class.php’ (include_path=’.;Z:usrlocalphp5pear;/usr/local/php5/PEAR’) in Z:homesite.comwwwcabinetindex.php on line 4
Сама cms использует для работы smarty
И я сначала подумал, что этот smarty конфликтует с каким-нибудь API, но такая ошибка появляется всегда, как в основном файле модуля появляется команда require_onceПомогите решить проблему позязя))
Вот сам основной файл подключаемого модуля
-
define(‘INCLUDE_CHECK’,true);
-
require_once(‘./smarty/libs/Smarty.class.php’);
-
include (‘./include/config.php’);
-
include (‘./include/kassa_config.php’);
-
include (‘./include/func.php’);
-
$path = dirname(__FILE__);
-
$logger = new Logger(«./mcshop.log»);
-
$log_date = «[» . date(«d/m/Y H:i») . «] «;
-
$q = mysql_query(«SELECT `value` FROM `settings` WHERE `name`=’theme’;»,$sql);
-
$theme = mysql_result($q,0);
-
$theme_path = ‘./theme/’.$theme.’/’;
-
$tpl->template_dir = $theme_path;
-
$tpl->compile_dir = ‘./cache/’;
-
$tpl->cache_dir = ‘./cache/’;
-
$tpl->assign(‘path’, $theme_path);
-
if(empty($_SESSION[‘id’])) {
-
// Тут делаем авторизацию
-
$tpl->assign(‘title’, ‘Авторизация’);
-
if(isset($_GET[‘error’])) {
-
$tpl->assign(‘errno’, ‘Неверный логин или пароль!’);
-
$logger->WriteLine($log_date . «Неудачная попытка авторизации с ip: » . $_SERVER[‘REMOTE_ADDR’]);
-
$tpl->assign(‘title’, ‘Личный Кабинет’);
-
$tpl->display(‘guest.tpl’);
-
$username = mysql_real_escape_string($_SESSION[‘name’]);
-
$right = privelegie($username, $db_users, $db_users_name, $sql);
-
$q = mysql_query(«SELECT money FROM {$db_users} WHERE {$db_users_name}=’$username’;»,$sql);
-
$tpl->assign(‘money’, mysql_result($q,0));
-
$tpl->assign(‘username’, $username);
-
$q = mysql_query(«SELECT value FROM settings WHERE name=’ip’ OR name=’port’;»,$sql);
-
$ip = mysql_result($q,0);
-
$port = mysql_result($q,1);
-
$settings = GetSettings($sql);
-
$server = Server($ip,$port);
-
if(!isset($server[‘name’])) $server[‘name’] = ‘Неопознанно’;
-
$tpl->assign(«shop_id»,$shop_id);
-
$tpl->assign(«right»,$right);
-
$tpl->assign(«map_enabled»,$settings[‘map_enabled’]);
-
$tpl->assign(‘srv_name’, $server[‘name’]);
-
$tpl->assign(‘ip’, ‘ip=’.$ip.’&port=’.$port);
-
$tpl->assign(‘navigation’, ‘menu.tpl’);
-
if(!isset($_GET[‘page’]) || $_GET[‘page’] == ») {
-
$tpl->assign(‘title’, ‘Личный Кабинет’);
-
$tpl->assign(‘content’, ‘skin.tpl’);
-
include(«./modules/blocks_main.php»);
-
include(«./modules/skin.php»);
-
include(«./modules/cp.php»);
-
$tpl->assign(‘welcome1’, ‘Добро пожаловать ‘.$username.’!’);
-
$tpl->assign(‘welcome2’, ‘Это ваш личный кабинет на игровом сервере ‘.$server[‘name’]);
-
$full_path = ‘./theme/’.$theme.’/’.$_GET[‘page’].’.tpl’;
-
if(!file_exists($full_path)) {
-
$tpl->assign(‘title’, ‘Ошибка 404’);
-
$tpl->assign(‘content’, ‘error.tpl’);
-
$tpl->assign(‘welcome1’, ‘Ошибка 404’);
-
$tpl->assign(‘welcome2’, »);
-
if($_GET[‘page’] == ‘buy’) {
-
$tpl->assign(‘title’, ‘Покупка статуса’);
-
include(«./modules/buy.php»);
-
$tpl->assign(‘welcome1’, ‘Покупка статуса’);
-
$tpl->assign(‘welcome2’, ‘Здесь вы можете купить игровой статус’);
-
if($_GET[‘page’] == ‘skin’) {
-
$tpl->assign(‘title’, ‘Сменить скин’);
-
include(«./modules/skin.php»);
-
$tpl->assign(‘content’, ‘skin.tpl’);
-
$tpl->assign(‘welcome1’, ‘Смена скина’);
-
$tpl->assign(‘welcome2’, ‘Здесь вы можете изменить свой игровой скин’);
-
if($_GET[‘page’] == ‘support’) {
-
$tpl->assign(‘title’, ‘Техническая поддержка’);
-
include(«./modules/support.php»);
-
$tpl->assign(‘content’, ‘support.tpl’);
-
$tpl->assign(‘welcome1’, ‘Тех поддержка’);
-
$tpl->assign(‘welcome2’, ‘Здесь вы можете написать в тех. поддержку’);
-
if($_GET[‘page’] == ‘cp’) {
-
$tpl->assign(‘title’, ‘Дополнительные услуги’);
-
include(«./modules/cp.php»);
-
$tpl->assign(‘welcome1’, ‘Дополнительные услуги’);
-
$tpl->assign(‘welcome2’, ‘Здесь вы можете воспользоваться другими услугами сервера’);
-
if($_GET[‘page’] == ‘admin’) {
-
$tpl->assign(‘title’, ‘Панель администратора’);
-
include(«./modules/admin.php»);
-
$tpl->assign(‘welcome1’, ‘Панель администратора’);
-
$tpl->assign(‘welcome2’, ‘Здесь вы можете управлять магазином в зависимости от Ваших прав’);
-
if($_GET[‘page’] == ‘map’) {
-
$tpl->assign(‘title’, ‘Карта сервера’);
-
include(«./modules/map.php»);
-
$tpl->assign(‘welcome1’, ‘Карта сервера’);
-
$tpl->assign(‘welcome2’, ‘Здесь вы можете увидеть карту сервера’);
-
if($_GET[‘page’] == ‘blocks’) {
-
$tpl->assign(‘title’, ‘Продажа блоков’);
-
include(«./modules/blocks.php»);
-
$tpl->assign(‘welcome1’, ‘Продажа блоков’);
-
$tpl->assign(‘welcome2’, ‘Здесь вы можете купить необходимыа Вам для игры блоки’);
-
// Для интерфейсов оплаты
-
if($_GET[‘page’] == ‘success’) {
-
$tpl->assign(‘title’, ‘Пополнение счета’);
-
include(«./kassa/success.php»);
-
$tpl->assign(‘welcome1’, ‘Пополнение счета’);
-
$tpl->assign(‘welcome2’, »);
-
if($_GET[‘page’] == ‘fail’) {
-
$tpl->assign(‘title’, ‘Пополнение счета’);
-
include(«./kassa/fail.php»);
-
$tpl->assign(‘welcome1’, ‘Пополнение счета’);
-
$tpl->assign(‘welcome2’, »);
-
if($_GET[‘page’] == ‘quit’) {
-
header(«Location: index.php»);
-
$tpl->display(‘main.tpl’);
-
iliavlad
Активный пользователь- С нами с:
- 24 янв 2009
- Сообщения:
- 1.689
- Симпатии:
- 4
Re: [Помогите] Fatal error: require_once()
у тебя в папке Z:homesite.comwwwcabinet есть папка smarty ?
-
- С нами с:
- 16 июл 2013
- Сообщения:
- 11
- Симпатии:
- 0
Re: [Помогите] Fatal error: require_once()
да
и папка и все файлы имеются -
Команда форума
Модератор- С нами с:
- 11 июн 2010
- Сообщения:
- 10.818
- Симпатии:
- 1.171
- Адрес:
- там-сям
require/include ищут файл относительно папки с «точкой входа», а не относительно папки с файлом в котором стоит этот require/include.
поясню:
если наш запрос обрабатывается файлом
Z:homesite.comwwwindex.php
который подключает, например файл ‘./cabinet/ololo.php’ , то есть уже
Z:homesite.comwwwcabinetololo.php
а тот, в свою очередь пытается подключить ‘./smarty/libs/Smarty.class.php’ , то этот файл будет искаться в
Z:homesite.comwwwsmartylibsSmarty.class.php — относительно первого файла!!! никаких «cabinet» здесь уже не наблюдаемДобавлено спустя 5 минут 13 секунд:
хотите инклудить относительно текущего файла? делайте так:-
include __DIR__.‘/path/to/file.php’; // начиная с PHP 5.3
или
-
include dirname(__FILE__).‘/path/to/file.php’; // во всех версиях PHP
Добавлено спустя 3 минуты 57 секунд:p.s. ты глянь в свой код, там даже есть готовая переменная $path, которую ты можешь использовать для «умного» инклуда
-
- С нами с:
- 16 июл 2013
- Сообщения:
- 11
- Симпатии:
- 0
Re: [Помогите] Fatal error: require_once()
Спасибо вам огромное))
Благодаря вам сэкономил кучу времениАдреса поправил в основном фале руками, но есть ли какой нибудь инструмент, который исправит это автоматически?
-
Команда форума
Модератор- С нами с:
- 11 июн 2010
- Сообщения:
- 10.818
- Симпатии:
- 1.171
- Адрес:
- там-сям
а не надо автоматически. думать надо и индивидуально решать.
-
- С нами с:
- 16 июл 2013
- Сообщения:
- 11
- Симпатии:
- 0
-
вобще, достаточно было убрать «./»…
относительно include path они ищут файл
Пользователь 2314675 Заглянувший Сообщений: 5 |
Господа, помогите. Ни с того ни с чего сайт стал выдавать ошибку: PHP Fatal error: require_once(): Failed opening required ‘***/lib/phpmailer/class.phpmailer.php’ (include_path=’.:/usr/share/php’) in ***/bitrix/php_interface/mail.php on line 4 Файл существует и открывается, с правами тоже все норм. Ошибка периодически пропадала, потом появлялась снова. Хостеры проблему со своей стороны отрицают, вирусы не нашли. |
Пользователь 136059 Гуру Сообщений: 5418 |
#2 0 16.08.2018 13:27:32
А что с этом файле? Голосуй за идеи по развитию API Bitrix: |
||
Пользователь 2314675 Заглянувший Сообщений: 5 |
Функция отправки писем //require_once($_SERVER[‘DOCUMENT_ROOT’] . ‘/lib/phpmailer/class.phpmailer.php’); * **’, *** if (!$mail->send()) { |
Пользователь 136059 Гуру Сообщений: 5418 |
#4 0 16.08.2018 13:31:48
Это весь код файла? Голосуй за идеи по развитию API Bitrix: |
||
Пользователь 2314675 Заглянувший Сообщений: 5 |
#5 0 16.08.2018 13:35:57
Нет, но дело все равно не в этом, код дальше require_once не проходит |
||||
Мария Д., если файл запускается например из-под cron то понятно почему не работает — $_SERVER[‘DOCUMENT_ROOT’] нету. Может быть переопределение идет где-то? |
|
Пользователь 2314675 Заглянувший Сообщений: 5 |
Андрей Николаев, с $_SERVER[‘DOCUMENT_ROOT’] все хорошо, путь выдает |
Мария Д., т.е. если сделать var_dump($_SERVER[‘DOCUMENT_ROOT’] . ‘/lib/phpmailer/class.phpmailer.php’) то он выводит корректный путь к файлу? |
|
Пользователь 2314675 Заглянувший Сообщений: 5 |
Андрей Николаев, да, я ставила проверку на существование файла: if (file_exists($_SERVER[‘DOCUMENT_ROOT’] . ‘/lib/phpmailer/class.phpmailer.php’)) В итоге он выдавал Fatal error: require_once(). |
Пользователь 396250 Постоянный посетитель Сообщений: 78 |
#10 0 09.06.2020 15:13:46 проверьте существует ли файл на сервере |
Пользователь 5010546 Заглянувший Сообщений: 1 |
#11 0 10.02.2021 11:38:15 Здравствуйте! Помогите, пожалуйста! Только очень подробно! я экстра-новичок. Пыталась загрузить резервную копию сайта и в момент загрузки — отменилась установка. В результате я не могу войти в панель администрирования и сайт недоступен. Сообщение: Fatal error: require(): Failed opening required ‘/home/p/pozniav3/zelaqua.com/public_html/bitrix/modules/main/interface/desktop.php’ (include_path=’.:/usr/share/php’) in /home/p/pozniav3/zelaqua.com/public_html/bitrix/admin/index.php on line 2 |
Антон Шевчук // Web-разработчик
Не совершает ошибок только тот, кто ничего не делает, и мы тому пример – трудимся не покладая рук над созданием рабочих мест для тестировщиков 🙂
О да, в этой статье я поведу свой рассказа об ошибках в PHP, и том как их обуздать.
Ошибки
Разновидности в семействе ошибок
Перед тем как приручать ошибки, я бы рекомендовал изучить каждый вид и отдельно обратить внимание на самых ярких представителей.
Чтобы ни одна ошибка не ушла незамеченной потребуется включить отслеживание всех ошибок с помощью функции error_reporting(), а с помощью директивы display_errors включить их отображение:
<?php error_reporting(E_ALL); ini_set('display_errors', 1);
Фатальные ошибки
Самый грозный вид ошибок – фатальные, они могут возникнуть как при компиляции, так и при работе парсера или PHP-скрипта, выполнение скрипта при этом прерывается.
E_PARSE
Это ошибка появляется, когда вы допускаете грубую ошибку синтаксиса и интерпретатор PHP не понимает, что вы от него хотите, например если не закрыли фигурную или круглую скобочку:
<?php /** Parse error: syntax error, unexpected end of file */ {
Или написали на непонятном языке:
<?php /** Parse error: syntax error, unexpected '...' (T_STRING) */ Тут будет ошибка парсера
Лишние скобочки тоже встречаются, и не важно круглые либо фигурные:
<?php /** Parse error: syntax error, unexpected '}' */ }
Отмечу один важный момент – код файла, в котором вы допустили parse error не будет выполнен, следовательно, если вы попытаетесь включить отображение ошибок в том же файле, где возникла ошибка парсера то это не сработает:
<?php // этот код не сработает error_reporting(E_ALL); ini_set('display_errors', 1); // т.к. вот тут ошибка парсера
E_ERROR
Это ошибка появляется, когда PHP понял что вы хотите, но сделать сие не получилось ввиду ряда причин, так же прерывает выполнение скрипта, при этом код до появления ошибки сработает:
Не был найден подключаемый файл:
/** Fatal error: require_once(): Failed opening required 'not-exists.php' (include_path='.:/usr/share/php:/usr/share/pear') */ require_once 'not-exists.php';
Было брошено исключение (что это за зверь, расскажу немного погодя), но не было обработано:
/** Fatal error: Uncaught exception 'Exception' */ throw new Exception();
При попытке вызвать несуществующий метод класса:
/** Fatal error: Call to undefined method stdClass::notExists() */ $stdClass = new stdClass(); $stdClass->notExists();
Отсутствия свободной памяти (больше, чем прописано в директиве memory_limit) или ещё чего-нить подобного:
/** Fatal Error: Allowed Memory Size */ $arr = array(); while (true) { $arr[] = str_pad(' ', 1024); }
Очень часто происходит при чтении либо загрузки больших файлов, так что будьте внимательны с вопросом потребляемой памяти
Рекурсивный вызов функции. В данном примере он закончился на 256-ой итерации, ибо так прописано в настройках xdebug:
/** Fatal error: Maximum function nesting level of '256' reached, aborting! */ function deep() { deep(); } deep();
Не фатальные
Данный вид не прерывает выполнение скрипта, но именно их обычно находит тестировщик, и именно они доставляют больше всего хлопот у начинающих разработчиков.
E_WARNING
Частенько встречается, когда подключаешь файл с использованием include
, а его не оказывается на сервере или ошиблись указывая путь к файлу:
/** Warning: include_once(): Failed opening 'not-exists.php' for inclusion */ include_once 'not-exists.php';
Бывает, если используешь неправильный тип аргументов при вызове функций:
/** Warning: join(): Invalid arguments passed */ join('string', 'string');
Их очень много, и перечислять все не имеет смысла…
E_NOTICE
Это самые распространенные ошибки, мало того, есть любители отключать вывод ошибок и клепают их целыми днями. Возникают при целом ряде тривиальных ошибок.
Когда обращаются к неопределенной переменной:
/** Notice: Undefined variable: a */ echo $a;
Когда обращаются к несуществующему элементу массива:
<?php /** Notice: Undefined index: a */ $b = array(); $b['a'];
Когда обращаются к несуществующей константе:
/** Notice: Use of undefined constant UNKNOWN_CONSTANT - assumed 'UNKNOWN_CONSTANT' */ echo UNKNOWN_CONSTANT;
Когда не конвертируют типы данных:
/** Notice: Array to string conversion */ echo array();
Для избежания подобных ошибок – будьте внимательней, и если вам IDE подсказывает о чём-то – не игнорируйте её:
E_STRICT
Это ошибки, которые научат вас писать код правильно, чтобы не было стыдно, тем более IDE вам эти ошибки сразу показывают. Вот например, если вызвали не статический метод как статику, то код будет работать, но это как-то неправильно, и возможно появление серьёзных ошибок, если в дальнейшем метод класса будет изменён, и появится обращение к $this
:
/** Strict standards: Non-static method Strict::test() should not be called statically */ class Strict { public function test() { echo 'Test'; } } Strict::test();
E_DEPRECATED
Так PHP будет ругаться, если вы используете устаревшие функции (т.е. те, что помечены как deprecated, и в следующем мажорном релизе их не будет):
/** Deprecated: Function split() is deprecated */ // популярная функция, всё никак не удалят из PHP // deprecated since 5.3 split(',', 'a,b');
В моём редакторе подобные функции будут зачёркнуты:
Обрабатываемые
Этот вид, которые разводит сам разработчик кода, я их уже давно не встречал, не рекомендую их вам заводить:
E_USER_ERROR
– критическая ошибкаE_USER_WARNING
– не критическая ошибкаE_USER_NOTICE
– сообщения которые не являются ошибками
Отдельно стоит отметить E_USER_DEPRECATED
– этот вид всё ещё используется очень часто для того, чтобы напомнить программисту, что метод или функция устарели и пора переписать код без использования оной. Для создания этой и подобных ошибок используется функция trigger_error():
/** * @deprecated Deprecated since version 1.2, to be removed in 2.0 */ function generateToken() { trigger_error('Function `generateToken` is deprecated, use class `Token` instead', E_USER_DEPRECATED); // ... // code ... // ... }
Теперь, когда вы познакомились с большинством видов и типов ошибок, пора озвучить небольшое пояснение по работе директивы
display_errors
:
- если
display_errors = on
, то в случае ошибки браузер получит html c текстом ошибки и кодом 200- если же
display_errors = off
, то для фатальных ошибок код ответа будет 500 и результат не будет возвращён пользователю, для остальных ошибок – код будет работать неправильно, но никому об этом не расскажет
Приручение
Для работы с ошибками в PHP существует 3 функции:
- set_error_handler() — устанавливает обработчик для ошибок, которые не обрывают работу скрипта (т.е. для не фатальных ошибок)
- error_get_last() — получает информацию о последней ошибке
- register_shutdown_function() — регистрирует обработчик который будет запущен при завершении работы скрипта. Данная функция не относится непосредственно к обработчикам ошибок, но зачастую используется именно для этого
Теперь немного подробностей об обработке ошибок с использованием set_error_handler()
, в качестве аргументов данная функция принимает имя функции, на которую будет возложена миссия по обработке ошибок и типы ошибок которые будут отслеживаться. Обработчиком ошибок может так же быть методом класса, или анонимной функцией, главное, чтобы он принимал следующий список аргументов:
$errno
– первый аргумент содержит тип ошибки в виде целого числа$errstr
– второй аргумент содержит сообщение об ошибке$errfile
– необязательный третий аргумент содержит имя файла, в котором произошла ошибка$errline
– необязательный четвертый аргумент содержит номер строки, в которой произошла ошибка$errcontext
– необязательный пятый аргумент содержит массив всех переменных, существующих в области видимости, где произошла ошибка
В случае если обработчик вернул true
, то ошибка будет считаться обработанной и выполнение скрипта продолжится, иначе — будет вызван стандартный обработчик, который логирует ошибку и в зависимости от её типа продолжит выполнение скрипта или завершит его. Вот пример обработчика:
<?php // включаем отображение всех ошибок, кроме E_NOTICE error_reporting(E_ALL & ~E_NOTICE); ini_set('display_errors', 1); // наш обработчик ошибок function myHandler($level, $message, $file, $line, $context) { // в зависимости от типа ошибки формируем заголовок сообщения switch ($level) { case E_WARNING: $type = 'Warning'; break; case E_NOTICE: $type = 'Notice'; break; default; // это не E_WARNING и не E_NOTICE // значит мы прекращаем обработку ошибки // далее обработка ложится на сам PHP return false; } // выводим текст ошибки echo "<h2>$type: $message</h2>"; echo "<p><strong>File</strong>: $file:$line</p>"; echo "<p><strong>Context</strong>: $". join(', $', array_keys($context))."</p>"; // сообщаем, что мы обработали ошибку, и дальнейшая обработка не требуется return true; } // регистрируем наш обработчик, он будет срабатывать на для всех типов ошибок set_error_handler('myHandler', E_ALL);
У вас не получится назначить более одной функции для обработки ошибок, хотя очень бы хотелось регистрировать для каждого типа ошибок свой обработчик, но нет – пишите один обработчик, и всю логику отображения для каждого типа описывайте уже непосредственно в нём
С обработчиком, который написан выше есть одна существенная проблема – он не ловит фатальные ошибки, и вместо сайта пользователи увидят лишь пустую страницу, либо, что ещё хуже, сообщение об ошибке. Дабы не допустить подобного сценария следует воспользоваться функцией register_shutdown_function() и с её помощью зарегистрировать функцию, которая всегда будет выполняться по окончанию работы скрипта:
function shutdown() { echo 'Этот текст будет всегда отображаться'; } register_shutdown_function('shutdown');
Данная функция будет срабатывать всегда!
Но вернёмся к ошибкам, для отслеживания появления в коде ошибки воспользуемся функцией error_get_last(), с её помощью можно получить информацию о последней выявленной ошибке, а поскольку фатальные ошибки прерывают выполнение кода, то они всегда будут выполнять роль “последних”:
function shutdown() { $error = error_get_last(); if ( // если в коде была допущена ошибка is_array($error) && // и это одна из фатальных ошибок in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR]) ) { // очищаем буфер вывода (о нём мы ещё поговорим в последующих статьях) while (ob_get_level()) { ob_end_clean(); } // выводим описание проблемы echo 'Сервер находится на техническом обслуживании, зайдите позже'; } } register_shutdown_function('shutdown');
Задание
Дополнить обработчик фатальных ошибок выводом исходного кода файла где была допущена ошибка, а так же добавьте подсветку синтаксиса выводимого кода.
О прожорливости
Проведём простой тест, и выясним – сколько драгоценных ресурсов кушает самая тривиальная ошибка:
/** * Этот код не вызывает ошибок */ // сохраняем параметры памяти и времени выполнения скрипта $memory = memory_get_usage(); $time= microtime(true); $a = ''; $arr = []; for ($i = 0; $i < 10000; $i++) { $arr[$a] = $i; } printf('%f seconds <br/>', microtime(true) - $time); echo number_format(memory_get_usage() - $memory, 0, '.', ' '), ' bytes<br/>';
В результате запуска данного скрипта у меня получился вот такой результат:
0.002867 seconds 984 bytes
Теперь добавим ошибку в цикле:
/** * Этот код содержит ошибку */ // сохраняем параметры памяти и времени выполнения скрипта $memory = memory_get_usage(); $time= microtime(true); $a = ''; $arr = []; for ($i = 0; $i < 10000; $i++) { $arr[$b] = $i; // тут ошиблись с именем переменной } printf('%f seconds <br/>', microtime(true) - $time); echo number_format(memory_get_usage() - $memory, 0, '.', ' '), ' bytes<br/>';
Результат ожидаемо хуже, и на порядок (даже на два порядка!):
0.263645 seconds 992 bytes
Вывод однозначен – ошибки в коде приводят к лишней прожорливости скриптов – так что во время разработки и тестирования приложения включайте отображение всех ошибок!
Тестирование проводил на PHP версии 5.6, в седьмой версии результат лучше – 0.0004 секунды против 0.0050 – разница только на один порядок, но в любом случае результат стоит прикладываемых усилий по исправлению ошибок
Где собака зарыта
В PHP есть спец символ «@» – оператор подавления ошибок, его используют дабы не писать обработку ошибок, а положится на корректное поведение PHP в случае чего:
<?php echo @UNKNOWN_CONSTANT;
При этом обработчик ошибок указанный в set_error_handler()
всё равно будет вызван, а факт того, что к ошибке было применено подавление можно отследить вызвав функцию error_reporting()
внутри обработчика, в этом случае она вернёт 0
.
Если вы в такой способ подавляете ошибки, то это уменьшает нагрузку на процессор в сравнении с тем, если вы их просто скрываете (см. сравнительный тест выше), но в любом случае, подавление ошибок это зло
Исключения
В эру PHP4 не было исключений (exceptions), всё было намного сложнее, и разработчики боролись с ошибками как могли, это было сражение не на жизнь, а на смерть… Окунуться в эту увлекательную историю противостояния можете в статье Исключительный код. Часть 1. Стоит ли её читать сейчас? Думаю да, ведь это поможет вам понять эволюцию языка, и раскроет всю прелесть исключений
Исключения — исключительные событие в PHP, в отличии от ошибок не просто констатируют наличие проблемы, а требуют от программиста дополнительных действий по обработке каждого конкретного случая.
К примеру, скрипт должен сохранить какие-то данные в кеш файл, если что-то пошло не так (нет доступа на запись, нет места на диске), генерируется исключение соответствующего типа, а в обработчике исключений принимается решение – сохранить в другое место или сообщить пользователю о проблеме.
Исключение – это объект который наследуется от класса Exception
, содержит текст ошибки, статус, а также может содержать ссылку на другое исключение которое стало первопричиной данного. Модель исключений в PHP схожа с используемыми в других языках программирования. Исключение можно инициировать (как говорят, “бросить”) при помощи оператора throw
, и можно перехватить (“поймать”) оператором catch
. Код генерирующий исключение, должен быть окружен блоком try
, для того чтобы можно было перехватить исключение. Каждый блок try
должен иметь как минимум один соответствующий ему блок catch
или finally
:
try { // код который может выбросить исключение if (rand(0, 1)) { throw new Exception('One') } else { echo 'Zero'; } } catch (Exception $e) { // код который может обработать исключение echo $e->getMessage(); }
В каких случаях стоит применять исключения:
- если в рамках одного метода/функции происходит несколько операций которые могут завершиться неудачей
- если используемый вами фреймверк или библиотека декларируют их использование
Для иллюстрации первого сценария возьмём уже озвученный пример функции для записи данных в файл – помешать нам может очень много факторов, а для того, чтобы сообщить выше стоящему коду в чем именно была проблема необходимо создать и выбросить исключение:
$directory = __DIR__ . DIRECTORY_SEPARATOR . 'logs'; // директории может не быть if (!is_dir($directory)) { throw new Exception('Directory `logs` is not exists'); } // может не быть прав на запись в директорию if (!is_writable($directory)) { throw new Exception('Directory `logs` is not writable'); } // возможно кто-то уже создал файл, и закрыл к нему доступ if (!$file = @fopen($directory . DIRECTORY_SEPARATOR . date('Y-m-d') . '.log', 'a+')) { throw new Exception('System can't create log file'); } fputs($file, date('[H:i:s]') . " donen"); fclose($file);
Соответственно ловить данные исключения будем примерно так:
try { // код который пишет в файл // ... } catch (Exception $e) { // выводим текст ошибки echo 'Не получилось: '. $e->getMessage(); }
В данном примере приведен очень простой сценарий обработки исключений, когда у нас любая исключительная ситуация обрабатывается на один манер. Но зачастую – различные исключения требуют различного подхода к обработке, и тогда следует использовать коды исключений и задать иерархию исключений в приложении:
// исключения файловой системы class FileSystemException extends Exception {} // исключения связанные с директориями class DirectoryException extends FileSystemException { // коды исключений const DIRECTORY_NOT_EXISTS = 1; const DIRECTORY_NOT_WRITABLE = 2; } // исключения связанные с файлами class FileException extends FileSystemException {}
Теперь, если использовать эти исключения то можно получить следующий код:
try { // код который пишет в файл if (!is_dir($directory)) { throw new DirectoryException('Directory `logs` is not exists', DirectoryException::DIRECTORY_NOT_EXISTS); } if (!is_writable($directory)) { throw new DirectoryException('Directory `logs` is not writable', DirectoryException::DIRECTORY_NOT_WRITABLE); } if (!$file = @fopen($directory . DIRECTORY_SEPARATOR . date('Y-m-d') . '.log', 'a+')) { throw new FileException('System can't open log file'); } fputs($file, date('[H:i:s]'') . " donen"); fclose($file); } catch (DirectoryException $e) { echo 'С директорией возникла проблема: '. $e->getMessage(); } catch (FileException $e) { echo 'С файлом возникла проблема: '. $e->getMessage(); } catch (FileSystemException $e) { echo 'Ошибка файловой системы: '. $e->getMessage(); } catch (Exception $e) { echo 'Ошибка сервера: '. $e->getMessage(); }
Важно помнить, что Exception — это прежде всего исключительное событие, иными словами исключение из правил. Не нужно использовать их для обработки очевидных ошибок, к примеру, для валидации введённых пользователем данных (хотя тут не всё так однозначно). При этом обработчик исключений должен быть написан в том месте, где он будет способен его обработать. К примеру, обработчик для исключений вызванных недоступностью файла для записи должен быть в методе, который отвечает за выбор файла или методе его вызывающем, для того что бы он имел возможность выбрать другой файл или другую директорию.
Так, а что будет если не поймать исключение? Вы получите “Fatal Error: Uncaught exception …”. Неприятно.
Чтобы избежать подобной ситуации следует использовать функцию set_exception_handler() и установить обработчик для исключений, которые брошены вне блока try-catch и не были обработаны. После вызова такого обработчика выполнение скрипта будет остановлено:
// в качестве обработчика событий // будем использовать анонимную функцию set_exception_handler(function($exception) { /** @var Exception $exception */ echo $exception->getMessage(), "<br/>n"; echo $exception->getFile(), ':', $exception->getLine(), "<br/>n"; echo $exception->getTraceAsString(), "<br/>n"; });
Ещё расскажу про конструкцию с использованием блока finally
– этот блок будет выполнен вне зависимости от того, было выброшено исключение или нет:
try { // код который может выбросить исключение } catch (Exception $e) { // код который может обработать исключение // если конечно оно появится } finally { // код, который будет выполнен при любом раскладе }
Для понимания того, что это нам даёт приведу следующий пример использования блока finally
:
try { // где-то глубоко внутри кода // соединение с базой данных $handler = mysqli_connect('localhost', 'root', '', 'test'); try { // при работе с БД возникла исключительная ситуация // ... throw new Exception('DB error'); } catch (Exception $e) { // исключение поймали, обработали на своём уровне // и должны его пробросить вверх, для дальнейшей обработки throw new Exception('Catch exception', 0, $e); } finally { // но, соединение с БД необходимо закрыть // будем делать это в блоке finally mysqli_close($handler); } // этот код не будет выполнен, если произойдёт исключение в коде выше echo "Ok"; } catch (Exception $e) { // ловим исключение, и выводим текст echo $e->getMessage(); echo "<br/>"; // выводим информацию о первоначальном исключении echo $e->getPrevious()->getMessage(); }
Т.е. запомните – блок finally
будет выполнен даже в том случае, если вы в блоке catch
пробрасываете исключение выше (собственно именно так он и задумывался).
Для вводной статьи информации в самый раз, кто жаждет ещё подробностей, то вы их найдёте в статье Исключительный код 😉
Задание
Написать свой обработчик исключений, с выводом текста файла где произошла ошибка, и всё это с подсветкой синтаксиса, так же не забудьте вывести trace в читаемом виде. Для ориентира – посмотрите как это круто выглядит у whoops.
PHP7 – всё не так, как было раньше
Так, вот вы сейчас всю информацию выше усвоили и теперь я буду грузить вас нововведениями в PHP7, т.е. я буду рассказывать о том, с чем вы столкнётесь через год работы PHP разработчиком. Ранее я вам рассказывал и показывал на примерах какой костыль нужно соорудить, чтобы отлавливать критические ошибки, так вот – в PHP7 это решили исправить, но как обычно завязались на обратную совместимость кода, и получили хоть и универсальное решение, но оно далеко от идеала. А теперь по пунктам об изменениях:
- при возникновении фатальных ошибок типа
E_ERROR
или фатальных ошибок с возможностью обработкиE_RECOVERABLE_ERROR
PHP выбрасывает исключение - эти исключения не наследуют класс Exception (помните я говорил об обратной совместимости, это всё ради неё)
- эти исключения наследуют класс Error
- оба класса Exception и Error реализуют интерфейс Throwable
- вы не можете реализовать интерфейс Throwable в своём коде
Интерфейс Throwable
практически полностью повторяет нам Exception
:
interface Throwable { public function getMessage(): string; public function getCode(): int; public function getFile(): string; public function getLine(): int; public function getTrace(): array; public function getTraceAsString(): string; public function getPrevious(): Throwable; public function __toString(): string; }
Сложно? Теперь на примерах, возьмём те, что были выше и слегка модернизируем:
try { // файл, который вызывает ошибку парсера include 'e_parse_include.php'; } catch (Error $e) { var_dump($e); }
В результате ошибку поймаем и выведем:
object(ParseError)#1 (7) { ["message":protected] => string(48) "syntax error, unexpected 'будет' (T_STRING)" ["string":"Error":private] => string(0) "" ["code":protected] => int(0) ["file":protected] => string(49) "/www/education/error/e_parse_include.php" ["line":protected] => int(4) ["trace":"Error":private] => array(0) { } ["previous":"Error":private] => NULL }
Как видите – поймали исключение ParseError, которое является наследником исключения Error
, который реализует интерфейс Throwable
, в доме который построил Джек. Ещё есть другие, но не буду мучать – для наглядности приведу иерархию исключений:
interface Throwable |- Exception implements Throwable | |- ErrorException extends Exception | |- ... extends Exception | `- ... extends Exception `- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- ArithmeticError extends Error | `- DivisionByZeroError extends ArithmeticError `- AssertionError extends Error
TypeError – для ошибок, когда тип аргументов функции не совпадает с передаваемым типом:
try { (function(int $one, int $two) { return; })('one', 'two'); } catch (TypeError $e) { echo $e->getMessage(); }
ArithmeticError – могут возникнуть при математических операциях, к примеру когда результат вычисления превышает лимит выделенный для целого числа:
try { 1 << -1; } catch (ArithmeticError $e) { echo $e->getMessage(); }
DivisionByZeroError – ошибка деления на ноль:
try { 1 / 0; } catch (ArithmeticError $e) { echo $e->getMessage(); }
AssertionError – редкий зверь, появляется когда условие заданное в assert() не выполняется:
ini_set('zend.assertions', 1); ini_set('assert.exception', 1); try { assert(1 === 0); } catch (AssertionError $e) { echo $e->getMessage(); }
При настройках production-серверов, директивы
zend.assertions
иassert.exception
отключают, и это правильно
Задание
Написать универсальный обработчик ошибок для PHP7, который будет отлавливать все возможные исключения.
При написании данного раздела были использованы материалы из статьи Throwable Exceptions and Errors in PHP 7
Отладка
Иногда для отладки кода нужно отследить что происходило с переменной или объектом на определённом этапе, для этих целей есть функция debug_backtrace() и debug_print_backtrace() которые вернут историю вызовов функций/методов в обратном порядке:
<?php function example() { echo '<pre>'; debug_print_backtrace(); echo '</pre>'; } class ExampleClass { public static function method () { example(); } } ExampleClass::method();
В результате выполнения функции debug_print_backtrace()
будет выведен список вызовов приведших нас к данной точке:
#0 example() called at [/www/education/error/backtrace.php:10] #1 ExampleClass::method() called at [/www/education/error/backtrace.php:14]
Проверить код на наличие синтаксических ошибок можно с помощью функции php_check_syntax() или же команды php -l [путь к файлу]
, но я не встречал использования оных.
Assert
Отдельно хочу рассказать о таком экзотическом звере как assert() в PHP, собственно это кусочек контрактной методологии программирования, и дальше я расскажу вам как я никогда его не использовал 🙂
Первый случай – это когда вам надо написать TODO прямо в коде, да так, чтобы точно не забыть реализовать заданный функционал:
// включаем вывод ошибок error_reporting(E_ALL); ini_set('display_errors', 1); // включаем asserts ini_set('zend.assertions', 1); ini_set('assert.active', 1); assert(false, "Remove it!");
В результате выполнения данного кода получим E_WARNING
:
Warning: assert(): Remove it! failed
PHP7 можно переключить в режим exception, и вместо ошибки будет всегда появляться исключение AssertionError
:
// включаем asserts ini_set('zend.assertions', 1); ini_set('assert.active', 1); // переключаем на исключения ini_set('assert.exception', 1); assert(false, "Remove it!");
В результате ожидаемо получаем не пойманный AssertionError
. При необходимости, можно выбрасывать произвольное исключение:
assert(false, new Exception("Remove it!"));
Но я бы рекомендовал использовать метки
@TODO
, современные IDE отлично с ними работают, и вам не нужно будет прикладывать дополнительные усилия и ресурсы для работы с ними
Второй вариант использования – это создание некоего подобия TDD, но помните – это лишь подобие. Хотя, если сильно постараться, то можно получить забавный результат, который поможет в тестировании вашего кода:
// callback-функция для вывода информации в браузер function backlog($script, $line, $code, $message) { echo "<h3>$message</h3>"; highlight_string ($code); } // устанавливаем callback-функцию assert_options(ASSERT_CALLBACK, 'backlog'); // отключаем вывод предупреждений assert_options(ASSERT_WARNING, false); // пишем проверку и её описание assert("sqr(4) == 16", "When I send integer, function should return square of it"); // функция, которую проверяем function sqr($a) { return; // она не работает }
Третий теоретический вариант – это непосредственно контрактное программирование – когда вы описали правила использования своей библиотеки, но хотите точно убедится, что вас поняли правильно, и в случае чего сразу указать разработчику на ошибку (я вот даже не уверен, что правильно его понимаю, но пример кода вполне рабочий):
/** * Настройки соединения должны передаваться в следующем виде * * [ * 'host' => 'localhost', * 'port' => 3306, * 'name' => 'dbname', * 'user' => 'root', * 'pass' => '' * ] * * @param $settings */ function setupDb ($settings) { // проверяем настройки assert(isset($settings['host']), 'Db `host` is required'); assert(isset($settings['port']) && is_int($settings['port']), 'Db `port` is required, should be integer'); assert(isset($settings['name']), 'Db `name` is required, should be integer'); // соединяем с БД // ... } setupDb(['host' => 'localhost']);
Никогда не используйте
assert()
для проверки входных параметров, ведь фактическиassert()
интерпретирует строковую переменную (ведёт себя какeval()
), а это чревато PHP-инъекцией. И да, это правильное поведение, т.к. просто отключив assert’ы всё что передаётся внутрь будет проигнорировано, а если делать как в примере выше, то код будет выполняться, а внутрь отключенного assert’a будет передан булевый результат выполнения
Если у вас есть живой опыт использования assert()
– поделитесь со мной, буду благодарен. И да, вот вам ещё занимательно чтива по этой теме – PHP Assertions, с таким же вопросом в конце 🙂
В заключение
Я за вас напишу выводы из данной статьи:
- Ошибкам бой – их не должно быть в вашем коде
- Используйте исключения – работу с ними нужно правильно организовать и будет счастье
- Assert – узнали о них, и хорошо
P.S. Спасибо Максиму Слесаренко за помощь в написании статьи
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
Closed
boja2015 opened this issue
Mar 13, 2017
· 9 comments
Comments
getting error on order success return url
url
/index.php?route=payment/razorpay/callback
error message
Fatal error: require_once(): Failed opening required ‘………/catalog/controller/payment/../../../../system/library/razorpay-sdk/Razorpay.php’ (include_path=’.:/usr/local/php71/pear’) in ……/catalog/controller/payment/razorpay.php on line 3
@boja2015 Could you please change
require_once __DIR__.'/../../../../system/library/razorpay-sdk/Razorpay.php';
to
require_once __DIR__.'/../../../system/library/razorpay-sdk/Razorpay.php';
?
@mayankamencherla i tried but same error appears on checkout page step6
Fatal error: require_once(): Failed opening required ‘/catalog/controller/extension/payment/../../../system/library/razorpay-sdk/Razorpay.php’ (include_path=’.:/usr/local/php71/pear’) in /catalog/controller/extension/payment/razorpay.php on line 3
@boja2015 Please replace:
require_once __DIR__.'/../../../system/library/razorpay-sdk/Razorpay.php';
to
require_once __DIR__.'/../../../../system/library/razorpay-sdk/Razorpay.php';
on line 3
i got the same error as mentioned in the first post
/index.php?route=payment/razorpay/callback
Fatal error: Uncaught Error: Class ‘Controllerpaymentrazorpay’ not found in
/system/storage/modification/system/engine/action.php:43 Stack trace: #0
/catalog/controller/startup/router.php(25): Action->execute(Object(Registry)) #1
/system/storage/modification/system/engine/action.php(51): ControllerStartupRouter->index() #2
/system/engine/front.php(34): Action->execute(Object(Registry)) #3
/system/engine/front.php(29): Front->execute(Object(Action)) #4
/system/framework.php(103): Front->dispatch(Object(Action), Object(Action)) #5
/system/startup.php(124): require_once(‘/home/machpowe/…’) #6
/index.php(19): start(‘catalog’) #7 {main} thrown in /system/storage/modification/system/engine/action.php on line 43
Hi
please update on the above issue
» Fatal error: Uncaught Error: Class ‘Controllerpaymentrazorpay’ not found in
/system/storage/modification/system/engine/action.php:43 Stack trace: #0 «
@boja2015 It seems like the installation wasn’t performed correctly. Could you please delete all the files and ensure you merge the folders correctly? Please ensure that the contents of the extension folder is put in correctly to your opencart’s extension folder?
Fatal error: require(): Failed opening required ‘Admin/view/index.php’ (include_path=’C:xamppphpPEAR’) in C:xampphtdocs3rdyearProjectSPSv1.1PHPfileAdminRequestHandlerRoute.php on line 12
Ive got an error on this. i think i used the correct path. How to solve it? Thank you.
@Joseph2398 — Could you please tell the version of opencart you are using?
Please try to use latest releases based on Open-cart version opencart2 : 3.0.0 and opencart3 : 4.0.0
-
#1
Ошибка при инклуде, хотя файл есть
В коде:
require_once(‘../../prepare.inc’);
Интерпретатор выдает ошибку:
Warning: require_once(prepare.inc) [function.require-once]: failed to open stream: No such file or directory in G:serveralien****includestandart_classesCustomActionsEditItemAction.class.php on line 3
Fatal error: require_once() [function.require]: Failed opening required ‘prepare.inc’ (include_path=’.;C:php5pear’) in G:serveralien****includestandart_classesCustomActionsEditItemAction.class.php on line 3
Файл 100% существует, к тому же, его правильно инклудит среда разработки (т.к. видно определение классов). Или это может быть связано с тем, что файл, который вызывает ошибку, сам инклудится в том prepare.inc ? Т.е. получает как бы кольцо, но раньше таких проблем не было..
Mr_Max
Первый класс. Зимние каникулы ^_^
-
#3
Используйте абсолютные пути.
PHP:
require_once dirname(__FILE__).'/../../prepare.inc';
-
#4
Или это может быть связано с тем, что файл, который вызывает ошибку, сам инклудится в том prepare.inc
если получается кольцо, то пхп так и пишет — ПОЛУЧАЕТСЯ КОЛЬЦО
а если он пишет No such file or directory, то выучить надо английский хотя бы в таком примитивном объеме трех слов
-~{}~ 20.08.07 09:17:
Sanchez
никто не сомневается, что файл существует.
просто путь к нему надо указывать тот, который есть, а не тот, которого нет.
дело не в файле. а в программисте. который путь указывает.
это может быть связано с тем, что файл, который вызывает ошибку, сам инклудится в том prepare.inc
поясни-ка эту глубокую мысль поподробнее.
у тебя есть файл, prepare.inc
в котором написано include EditItemAction.class.php
а в нем написано include prepare.inc?
-
#5
Ребята, я знаю что такое относительный и абсолютный путь, что такое права доступа и регистр. Последние два фактора исключены, т.к. я работаю под виндой.
По поводу существования файла — если бы я не был уверен, что указал путь правильно, я бы не писал сюда. Этот файл видит по указанному пути среда разработки — иначе бы она написала, что файл не найден и не подгрузила бы в Intellisence описания классов.
———-
поясни-ка эту глубокую мысль поподробнее.
у тебя есть файл, prepare.inc
в котором написано include EditItemAction.class.php
а в нем написано include prepare.inc?
———-
Да, но не include, а require_once, поэтому в принципе «кольца» не должно быть, я на всякий случай спросил.
-
#6
ню-ню. если хватило ума придумать алгоритм с такими рекурсивными инклюдами, то я не удивлюсь вообще никаким проблемам. просто исходя из образа мышления аффтара
В любом случае, раз ты такой умный и сам все знаешь, то форум тебе помочь ничем не сможет.
Ответ на свой вопрос ты получил.
-
#7
а причём тут среда разработки? мало ли что она видит
-
#8
Андрейка
Ну как же?
Если я вижу из своего окна винный магазин, то все остальные должны тоже видеть. Ведь смотрят всев одну и ту же сторону — в окно!
-
#9
Инклюд я делал исключительно для Intellisence, т.к. иначе среда не распознает что этот файл был проинклуден в другом и не подгружает описания классов, а без интеллисенса работать тяжело. В окончательном варианте само собой это все убирается, но мне интересно ПОЧЕМУ в данном случае интерпретатор не может найти файл.
Ну собственно ничего нового я в этой теме и не узнал, кроме понтов некоторых товарищей)))
-
#10
Sanchez
как это — не узнал? Тебе объяснили, например, пользу знания иностранных языков вообще, и что «failed to open stream» не означает «получает как бы кольцо» — в частности.
А то ты сам-то сообразить не догадался. Ни с понтами, ни без.
-
#11
Ой ладно, по существу не можете ответить (кроме Mr_Max, но к сожалению его советы я уже знал и пытался использовать сам), значит надо максимально опустить человека — железная логика)))
Модератору — просьба закрыть эту тему.
-
#12
чувак.
ты задал идиотский вопрос.
и теперь еще обижаешься, что тебя «опустили»?
скромнее надо быть.
закрывать тему я не буду.
вдруг кто-нибудь еще захочет оттянуться.
-~{}~ 20.08.07 12:29:
очередной раз напишу пояснение для тех, кто на основании таких топиков делает вывод, что на пхпклубе «всех опускают».
в интернете полно лохов, которые полагают себя самыми умными, и очень мало действительно умных людей.
различие между ними очень простое.
умный человек, столкнувшись с загадочной ситуацией, которой, по его мнению, никак не может быть, делает две вещи:
1. 10 раз все проверяет и перепроверяет. придя на форум — ПЕРВЫМ ДЕЛОМ предоставляет эти результаты проверок. мол — убедитесь, я не из пальца все высосал. Поскольку сам ПОНИМАЮ, что ситуация дурацкая.
2. Делает все, что ему говорят на форуме и снова предоставляет результаты.
что делает лох?
тоже две вещи
1. Первым делом идет на форум, чтобы ему быстро решили его проблему. причем отвечающие должны сами догадаться по весьма куцому описанию обо всех нюансах, а так же о том, что автор пробовал, и какой получил результат.
2. Если ответ кажется ему глупым или «не по существу», то ответ отбрасывается, а начинаются рассуждения о том, какие все вокруг плохие и «с понтами». И, разумеется, все он читал и все знает.
Виноватым, в обязательном порядке, оказывается тот, кто отвечал. Сам же задавший вопрос — безгрешен.
-
#13
опускают на зоне. что за базары внатуре. есть же красивый литературный язык. Правильно говорить «унизили применением анального секса»
-
#14
Автор оригинала: SiMM
Используйте абсолютные пути.PHP:
require_once dirname(__FILE__).'/../../prepare.inc';
ну раз уже так, тогда
PHP:
require_once realpath(dirname(__FILE__) . '/../../prepare.inc');
-
#15
я бы даже сказал, что echo вместо require_once
но товарищ же все знает и все пробовал сам
-
#16
Вот это уже более конструктивно.
Не надо судить об уровне знаний человека (лох или не лох) и его опыте по количеству сообщений. У меня возникла проблема, с которой я раньше не сталкивался — самому решить ее не получилось. Я думал может я перепутал уровни вложенности, проверил — правильно. Проблемы с регистром и правами доступа исключены, т.к. я работаю на винде.
Написал следующую строку в EditItemAction.class.php:
<?php
print realpath(dirname(__FILE__) . ‘/../../prepare.inc’);
require_once(‘../../prepare.inc’);
Результат — на картинках.
Как вы видите, по нужному пути файл существует. А ошибка все равно остается.
Я бы мог убрать этот инклуд, т.к. он не нужен реально для работы сайта, но как я говорил — мне он нужен в отладочных целях чтобы работал Intellisence, и просто интересно ОТКУДА берется эта ошибка.
-
#17
Не надо судить об уровне знаний человека (лох или не лох) и его опыте по количеству сообщений.
правильно.
судить надо по содержанию.
что человек пишет — так по нему и судят. только так.
-
#18
А не может ошибка возникать из-за того, что пока prepare.inc инклудит EditItemAction.class.php, он заблокирован для чтения (т.к. выполняется), поэтому EditItemAction.class.php не может заинклудить prepare.inc ?
-
#19
require_once(‘../../prepare.inc’);
слушай, ты издеваешься, или как?
тебе раз 15 уже сказали использовать полный путь, но ты все равно упорно пишешь относительный.
это у тебя принцип такой, что ли?
-~{}~ 20.08.07 13:16:
сообщения об ошибках надо приводить полностью.
и ТЕКСТОМ, а не какие-то огрызки на картинках.
свой драгоценный сайт можешь затирать сколько угодно — никому он даром не нужен.
а вот ТЕКСТ сообщения об ошибке, надо приводить ПОЛНОСТЬЮ.
если тебе он ничем не помогает, это еще не значит, что он никому вообще не нужен
-
#20
Действительно с полным путем проинклудилось, спасибо. А почему он с относительным не хотел?
Полная ошибка такая:
******************************************************************************************
Warning: require_once(W:domainsopen1/system/startup.php): failed to open stream: No such file or directory in D:OpenServerdomainsopen1index.php on line 17
Fatal error: require_once(): Failed opening required ‘W:domainsopen1/system/startup.php’ (include_path=’.;D:OpenServermodulesphpPHP-5.4.22;D:OpenServermodulesphpPHP-5.4.22PEARpear’) in D:OpenServerdomainsopen1index.php on line 17
******************************************************************************************
Установил CMS ocStore-1.5.5.1.1 , пока в ней работал пару часов, поменял шаблон, картинки в нем настраивал…. И потом раз и возникает при очередном обновлении страницы такая вот ошибка. В код я нигде не вмешивался, даже не делал ручной перевод отдельных слов.
Главное вот что:
1) переустановил я опять все заново и через пару часов опять второй раз такая фигня, как будто кто то считает количество обновления страниц, потому что это происходит через пару-тройку часов администриирования сайта.
2) происходит такое уже два раза,
Пишет что нет такой директории:
Warning: require_once(W:domainsopen1/system/startup.php): failed to open stream: No such file or directory in D:OpenServerdomainsopen1index.php on line 17
— но файл startup.php лежит , где и прописано, а в строке 17 находится команда
// Startup require_once(DIR_SYSTEM . 'startup.php');
-настройки опен сервера находятся в исходном заводском состоянии. жук в том , что все работало же пару часов , а потом само обрубается !!
— помогите , кто квалифицирован, а?
Добавлено спустя 2 часа 22 минуты 1 секунду:
Логи :
PHP отладка
[17-Jan-2014 02:57:23 Europe/Moscow] PHP Warning: require_once(W:domainsopen1/system/startup.php) [<a href=’function.require-once’>function.require-once</a>]: failed to open stream: No such file or directory in D:OpenServerdomainsopen1index.php on line 17
[17-Jan-2014 02:57:23 Europe/Moscow] PHP Fatal error: require_once() [<a href=’function.require’>function.require</a>]: Failed opening required ‘W:domainsopen1/system/startup.php’ (include_path=’.;D:OpenServermodulesphpPHP-5.3.27;D:OpenServermodulesphpPHP-5.3.27PEARpear’) in D:OpenServerdomainsopen1index.php on line 17
[17-Jan-2014 02:57:37 Europe/Moscow] PHP Warning: require_once(W:domainsopen1/system/startup.php) [<a href=’function.require-once’>function.require-once</a>]: failed to open stream: No such file or directory in D:OpenServerdomainsopen1index.php on line 17
[17-Jan-2014 02:57:37 Europe/Moscow] PHP Fatal error: require_once() [<a href=’function.require’>function.require</a>]: Failed opening required ‘W:domainsopen1/system/startup.php’ (include_path=’.;D:OpenServermodulesphpPHP-5.3.27;D:OpenServermodulesphpPHP-5.3.27PEARpear’) in D:OpenServerdomainsopen1index.php on line 17
[17-Jan-2014 02:57:41 Europe/Moscow] PHP Warning: require_once(W:domainsopen1/system/startup.php) [<a href=’function.require-once’>function.require-once</a>]: failed to open stream: No such file or directory in D:OpenServerdomainsopen1index.php on line 17
[17-Jan-2014 02:57:41 Europe/Moscow] PHP Fatal error: require_once() [<a href=’function.require’>function.require</a>]: Failed opening required ‘W:domainsopen1/system/startup.php’ (include_path=’.;D:OpenServermodulesphpPHP-5.3.27;D:OpenServermodulesphpPHP-5.3.27PEARpear’) in D:OpenServerdomainsopen1index.php on line 17
MySQL запросы
D:OpenServermodulesdatabaseMySQL-5.5.35binmysqld.exe, Version: 5.5.35-log (MySQL Community Server (GPL)). started with:
TCP Port: 3306, Named Pipe: (null)
Time Id Command Argument
MySQL отладка
140117 1:57:04 [Note] Plugin ‘FEDERATED’ is disabled.
140117 1:57:04 InnoDB: The InnoDB memory heap is disabled
140117 1:57:04 InnoDB: Mutexes and rw_locks use Windows interlocked functions
140117 1:57:04 InnoDB: Compressed tables use zlib 1.2.3
140117 1:57:05 InnoDB: Initializing buffer pool, size = 20.0M
140117 1:57:05 InnoDB: Completed initialization of buffer pool
140117 1:57:05 InnoDB: highest supported file format is Barracuda.
140117 1:57:05 InnoDB: Waiting for the background threads to start
140117 1:57:06 InnoDB: 5.5.35 started; log sequence number 1595675
140117 1:57:06 [Note] Server hostname (bind-address): ‘127.0.0.1’; port: 3306
140117 1:57:06 [Note] — ‘127.0.0.1’ resolves to ‘127.0.0.1’;
140117 1:57:06 [Note] Server socket created on IP: ‘127.0.0.1’.
140117 1:57:06 [Note] Event Scheduler: Loaded 0 events
140117 1:57:07 [Note] D:OpenServermodulesdatabaseMySQL-5.5.35binmysqld.exe: ready for connections.
Version: ‘5.5.35-log’ socket: » port: 3306 MySQL Community Server (GPL)
0 Пользователей и 1 Гость просматривают эту тему.
- 0 Ответов
- 111680 Просмотров
Периодически после переноса сайта с сервера на сервер может возникать ошибка следующего вида:
Fatal error: require_once() [function.require]: Failed opening required 'includes/joomla.php' (include_path='.:/usr/share/php5:/usr/share/php') in /home/site.ru/index.php on line 37
Суть ошибки заключается в том, что из корневого index.php файла не подключается файл includes/joomla.php. Причин возникновения этой ошибки может быть в принципе несколько.
Причина 1: некорректные настройки путей на сервере, т.е. для скрипта директорией выполнения является не корень сайта, а какая-то иная директория. И по относительному пути файл не находится. В этом случае можно попробовать побороть эту ошибку, путем замены в корневом index.php строчки:
require_once( ‘includes/joomla.php’ );
на
require_once( $mosConfig_absolute_path . ‘/includes/joomla.php’ );
Причина 2: некорректные права доступа к файлам после переноса сайта. Например, сегодня имела место ситуация, когда на файлах были права 750, и сервер отказывался их обрабатывать. После смены прав на 775, сайт снова заработал.