как возбудить стандартную ошибку PHP?

Духовность™

Продвинутый новичок
как возбудить стандартную ошибку PHP?

решил использовать __call для геттеров и сеттеров.

PHP:
function __call()
{
    // ...

    if ($action == 'get')
    {
        // ... 
    }
    else if ($action == 'set')
    {
        // ... 
    }
    else // нужно сделать Fatal error: Call to undefined method 
}
теперь мне нужно, что бы когда вызовется неизвестный метод $object->foo() в __сall была бы возбуждена стандартная ошибка:

Fatal error: Call to undefined method Object::foo() in Z:\home...

как енто сделать?
 

Духовность™

Продвинутый новичок
Исключение брось.
да не хочу я исключение. я хочу что бы у меня было написано, что

Fatal error: Call to undefined method Object::foo() in Z:\home\adverts\www\kernel\Module\User\Controller\BackendEdit.php on line 22

исключение предполагает, что мне нужно опять писать текст ошибки и т.д. а я хочу что бы PHP сам смог ошибку выдать.
 

Духовность™

Продвинутый новичок
наверно это нельзя сделать. иначе получится рекурсия и ошибки разработчика нельзя будет отличить от ошибок php.
 

Fortop

Новичок
На, это максимально близко к тому что ты хочешь.
PHP:
class E
{
  public function __call($name, $params)
  {
    if (method_exists($this, $name)) {
      $this->$name($params);
    } else {
      throw new Exception ('Call to undefined method ' .  __CLASS__ . '::' . $name . '()');
    }
  }

  private function callE($p) {
    var_dump($p);
  }
}

$aa = new E;
$aa->callE(1);
$aa->callD(2);
 

Вурдалак

Продвинутый новичок
Чем это:
PHP:
class E
{
    public function __call($name, $params)
    {
        if( method_exists($this, $name) ) {
            call_user_func_array(array($this, $name), $params);
        } else {
            trigger_error('Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR);
        }
    }
}

$e = new E();
$e->shit();
не ближе?
 

serglt

Анус, ой, Ахтунг
Да да Вурдалак, еще можно добавить debug_backtrace (); Что бы можно было видеть где беда была. Делал как то такое.
 

fixxxer

К.О.
Партнер клуба
В то время, как все заворачивают php-шные ошибки в исключения.... :)
 

serglt

Анус, ой, Ахтунг
Ну не будем разводить демагогию по этому поводу :)
На вкус и цвет как говорится. Везде есть свои плюсы и минусы.

-~{}~ 20.05.10 18:03:

[off]
Кстати все в курсе как ловить parse error? :)
А то могу рассказать как оно делается.
 

serglt

Анус, ой, Ахтунг
файл a.php
PHP:
<?
function shutdownHnd () {
	if (!$e = error_get_last ()) return;
	echo "Error: \n";
	print_r ($e);
}
register_shutdown_function ('shutdownHnd');
include "b.php";
Файл b.php
PHP:
<?
ghfksjhsf
gfhskjhgsdf
-~{}~ 20.05.10 18:36:

Чтоб хватать все ошибки вешаем два обработчика
PHP:
		set_error_handler ();
		register_shutdown_function ();
;)

-~{}~ 20.05.10 18:58:

Все шокированы и потеряли дар речи :)
 

fixxxer

К.О.
Партнер клуба
внимание, вопрос. А ЗАЧЕМ?

в unit test фреймворках и то с трудом представляю, ибо на этом этапе уже все деструкторы отработали и нам нечем, кроме стандартных php-функций, что-то сделать, а что ими тут сделаешь то умное.

а для остальных вещей, показ 500 ошибки/запись в лог и так штатными средствами делается :)
 

serglt

Анус, ой, Ахтунг
Автор оригинала: fixxxer
внимание, вопрос. А ЗАЧЕМ?

в unit test фреймворках и то с трудом представляю, ибо на этом этапе уже все деструкторы отработали и нам нечем, кроме стандартных php-функций, что-то сделать, а что ими тут сделаешь то умное.

а для остальных вещей, показ 500 ошибки/запись в лог и так штатными средствами делается :)
Очень не прав деструкторы еще не отработали.
Вот тебе еще один файл a.php b.php можешь взять старый
PHP:
<?

class Logger {
	function write ($str) {
		echo $str;
	}
}

class ErrorHandler {
	protected $logger;
	public static $inst = null;
	static function init ($logger) {
		if (!self::$inst) self::$inst = new self ($logger);
	}

	function __construct ($logger) {
		$this -> logger = $logger;
		register_shutdown_function (array ($this, 'shutdownHnd'));
		set_error_handler (array ($this, 'errorHnd'), E_ALL);
	}
	
	function shutdownHnd () {
	    if (!$e = error_get_last ()) return;
		$this -> errorHnd ($e ['type'], $e ['message'], $e ['file'], $e ['line']);
	}

	function errorHnd ($errno, $errstr, $errfile, $errline) {
		$this -> logger -> write ("$errno, $errstr, $errfile, $errline\n");
		return true;
	}
}

ErrorHandler::init (new Logger);

include 'b.php';
 

fixxxer

К.О.
Партнер клуба
>> Очень не прав деструкторы еще не отработали.

А вот это никто не гарантирует. В где-то 4.1 (не помню точно, когда это изменилось) шатдаун обрабатывался на очень поздней стадии. И ничто не гарантирует, что это опять не изменится. То есть по сути это хак. ;)

-~{}~ 21.05.10 00:02:

Собственно, то, что shutdown function сработает при fatal error, тоже никто не гарантирует. Для всяких отладочных фишечек это использовать можно, но того, кто это потащит в production, следует луить веслом по лицу.
 

serglt

Анус, ой, Ахтунг
А бывает нужно, например гавнаконфиг какого нить сайта кривенько записался у клиента - вот тебе мониторинг
Да в ряде случаев

Да и еще при парсе ероре и фатале - пхп не убивает коннекты к БД
На высоких нагрузках - на сервере копятся соединения и база ложится. В шотдауне можно это избежать
 

fixxxer

К.О.
Партнер клуба
>>А бывает нужно, например гавнаконфиг какого нить сайта кривенько записался у клиента - вот тебе мониторинг

>>На высоких нагрузках - на сервере копятся соединения и база ложится. В шотдауне можно это избежать


Это всего лишь означает, что надо отрывать руки и ноги тому кто написал такой говнокод.
 
Сверху