Внутри работает примерно так: Когда вызывает метод
startTracker()
в объекте конекта ставится флаг который сообщает внутренним методам что нужно записывать инфу SQL запросов. Затем при каждом SQL запросе через d7 конект создаётся объект \Bitrix\Main\Diag\SqlTrackerQuery в который записывается статистика запроса и сам запрос. Это объект попадает в \Bitrix\Main\Diag\SqlTracker и и результирующий объект(если он возвращается), и так пока не будет остановлен тракер. Флаг $reset очищает тракер и запускает трекер опять.
use Bitrix\Main\ArgumentException; ... function check($arProducts) { if(!is_array($arProducts)){ throw new ArgumentException('Input arProducts expected array', 'data'); }
<?php
/**
* User: James Gerat
* Date: 21.05.14
* Time: 20:37
*/
use Bitrix\Main;
class ExceptionHandlerFormatter
{
const MAX_CHARS = 30;
public static function format(\Exception $exception, $htmlMode = false)
{
$result = '['.get_class($exception).'] ';
if ($exception instanceof \ErrorException)
$result .= static::severityToString($exception->getSeverity());
$result .= "\n".static::getMessage($exception)."\n";
if ($exception instanceof Main\DB\SqlQueryException)
$result .= $exception->getQuery()."\n";
$fileLink = static::getFileLink($exception->getFile(), $exception->getLine());
$result .= $fileLink.(empty($fileLink) ? "" : "\n");
if ($htmlMode)
$result = Main\Text\String::htmlEncode($result);
$prevArg = null;
$trace = static::getTrace($exception);
foreach ($trace as $traceNum => $traceInfo)
{
if ($htmlMode)
$result .= "<hr>";
$traceLine = '#'.$traceNum.': ';
if (array_key_exists('class', $traceInfo))
$traceLine .= $traceInfo['class'].$traceInfo['type'];
if (array_key_exists('function', $traceInfo))
{
$traceLine .= $traceInfo['function'];
$traceLine .= static::getArguments($traceInfo['args']);
}
if ($htmlMode)
$traceLine = Main\Text\String::htmlEncode($traceLine);
if (array_key_exists('file', $traceInfo))
$traceLine .= "\n\t".static::getFileLink($traceInfo['file'], $traceInfo['line']);
else
$traceLine .= "\n\t".static::getFileLink(null, null);
$result .= $traceLine. "\n";
}
if ($htmlMode)
$result = '<pre class="exception">'.$result.'</pre>';
return $result;
}
protected static function getTrace(\Exception $exception)
{
$backtrace = $exception->getTrace();
$exceptionHandlerClass = "Bitrix\\Main\\Diag\\ExceptionHandler";
$result = array();
foreach ($backtrace as $item)
{
if (array_key_exists('class', $item) && ($item['class'] == $exceptionHandlerClass))
continue;
$result[] = $item;
}
return $result;
}
protected static function getMessage(\Exception $exception)
{
return $exception->getMessage().' ('.$exception->getCode().')';
}
public static function severityToString($severity)
{
switch ($severity)
{
case 1:
return 'E_ERROR';
break;
case 2:
return 'E_WARNING';
break;
case 4:
return 'E_PARSE';
break;
case 8:
return 'E_NOTICE';
break;
case 16:
return 'E_CORE_ERROR';
break;
case 32:
return 'E_CORE_WARNING';
break;
case 64:
return 'E_COMPILE_ERROR';
break;
case 128:
return 'E_COMPILE_WARNING';
break;
case 256:
return 'E_USER_ERROR';
break;
case 512:
return 'E_USER_WARNING';
break;
case 1024:
return 'E_USER_NOTICE';
break;
case 2048:
return 'E_STRICT';
break;
case 4096:
return 'E_RECOVERABLE_ERROR';
break;
case 8192:
return 'E_DEPRECATED';
break;
case 16384:
return 'E_USER_DEPRECATED';
break;
case 30719:
return 'E_ALL';
break;
default:
return 'UNKNOWN';
break;
}
}
protected static function getArguments($args)
{
if (!is_null($args))
{
$argsTmp = array();
foreach ($args as $arg)
$argsTmp[] = static::convertArgumentToString($arg);
return "(\n" . implode(",\n", $argsTmp) . "\n)";
}
return '()';
}
protected static function convertArgumentToString($arg)
{
$result = null;
switch (gettype($arg))
{
case 'boolean':
$result = $arg ? 'true' : 'false';
break;
case 'NULL':
$result = 'null';
break;
case 'integer':
case 'double':
case 'float':
$result = (string) $arg;
break;
case 'string':
if (is_callable($arg, false, $callableName))
{
$result = 'fs:'.$callableName;
}
elseif (class_exists($arg, false))
{
$result = 'c:'.$arg;
}
elseif (interface_exists($arg, false))
{
$result = 'i:'.$arg;
}
else
{
if (strlen($arg) > static::MAX_CHARS)
$result = '"'.substr($arg, 0, static::MAX_CHARS / 2).'...'.substr($arg, -static::MAX_CHARS / 2).'" ('.strlen($arg).')';
else
$result = '"'.$arg.'"';
}
break;
case 'array':
if (is_callable($arg, false, $callableName))
$result = 'fa:'.$callableName;
else
$result = print_r($arg,true);//'array('.count($arg).')';
break;
case 'object':
$result = print_r($arg,true);//'['.get_class($arg).']';
break;
case 'resource':
$result = 'r:'.get_resource_type($arg);
break;
default:
$result = 'unknown type';
break;
}
//return str_replace("\n", '\n', $result);
return $result;
}
protected static function getFileLink($file, $line)
{
if (!is_null($file) && !empty($file))
{
/** for WIN */
$file = Main\IO\Path::normalize($file);
return str_replace(Main\Application::getDocumentRoot(),'',$file).':'.$line;
}
return "";
}
}
Регистрируем новый объект вывода (например init.php) \Bitrix\Main\Application::getInstance()->getExceptionHandler()->setHandlerOutput(new ExceptionHandlerOutput()); Теперь если цепочка эсепшенов будет выглядеть так:
а если поставить константу define('FULL_EXCEPTION',true); оно же будет выглядеть так:
Прошу прощения что без особых подробностей, времени не хватает((( Если что не понятно пишите в комментариях, помогу чем смогу.
restartbuffer - вот где дибилизм, сначала отрабатываем все до этой команды - потом сбрасываем и типа до аякс кода "ничего не подключено" - этот костыль меня убивает до сих пор. Это же дегенератизм обрабатывать то что по запросу аякс не должно отрабатываться...
Может я изобрёл велосипед, может нет. Не судите строго, может кому пригодиться. Пришёл заказ. Три псд. Дизайн на всех трёх примерно один. НО правая колонка разная. На третьем её вообще нет. Задумался как сделать одним шаблоном. Ковырялся долго, не буду в даваться в подробности.В конце концов наткнулся на статью 1 и на статью 2, а также снова почитав это, мой мозг выдал примерно следующие:
Перво наперво мне нужна была функция "выбора-вывода" контента в область:
Если нам необходимо повлиять на вывод, в необходимом месте ставим:
<?right_content(2);?>
Результат: 1)Вывод компонента или другого кода через отложенные фукции 2)Отложенные функции внутри встраиваемого кода отрабатывают(проверял на примере css в дефолте) 3)Вывод дефолтного кода
Минусы: 1)Видимо в связи с тем как работают отложенные функции функция right_content не работает до объявления $APPLICATION->ShowProperty 2)В данном примере есть дефолтное значение, и оно успевает отработать до вызова right_content. Поэтому хоть и контетная часть передаётся правильно, но успевают подключится css,js,title и пр. Но они у меня не существенные и на скорость сайта сильно не влияют.
P.S. Выложил рабочий вариант, возможно что не окончательный Нормально отношусь к адекватной критике. Знаете как сделать лучше, готов выслушать)
Поправте если не прав: Подшивалов Иван презентацию читал, данная функция мне не подходит, потому что мне нужно было дефолтное значение(то есть когда не чего не задаётся)+ у меня только три вида колонки на куче страниц, объявлять это каждый раз накладно. Долганин Антон в дабавок к первому ответу могу сказать что данный курс не успел освоить, но эта часть мне попадалось когда разбирался Емельянов Сергей согласен, функции плохо описаны и понять их принцип работы можно только тестами
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».