Exceptions - прихващане

index

Super Moderator
Възможно ли е да прихвана exceptions , след като съм го throw без tray метода.
Идеята ми :

PHP:
class Name {

 function habibi()
{

 throw new Exceptions("ala bala ",001);

}

}

И после да прихвана грешката без да използвам
PHP:
try {
  Name::habibi();
} catch (Exception $e) {
    echo  $e->getMessage(), "\n";
}
 
За да се стартира "прихващача" трябва кода да е затворен в try конструкция. Това можеш да направиш и в най-най-горното ниво на приложението си - само в основния скрипт (който разбира се винаги се зарежда).
 
Идеята мие Exceptiona да го "изтрещи" (както казват някой гора ) във въздуха и после да го прихвана без tray.....Др идея е да направя клас който да има статичен метод и в него да се "изтрещават" грешките.И при евентуална грешка да спира кода... но идеята мие да го постигна с готовите неща :)
 
PHP:
class Name {


 function habibi()

{

 throw new Exceptions("ala bala ",001);

}



}
Като не зная кога и за какво ще се извика
Name::habibi();

И при евентуална грешка да "трещи" и да спира всички процеси след него. Тъй като Name::habibi(); ще се изпълнява първо.

PHP:
<?php
// nqkakyv kod 
for($i=0;$i<$maxrow;$i++)
{
  Name::habibi($value[$i]);

}

/*
 Тук да  гърми кода  защото някое от  $value[$i], не е валидно. И кода да спира тук. Като Опция exit(); не ми върши никаква работа :)
*/
 
PHP:
<?php
class MyExceptions {

    private static $object = null;
    public $problem = array();

    private function __construct() {}

    public function setProblem($msg, $code) {
        self::getInstance();
        $this->problem = array('msg' => $msg, 'code' => $code);
    }

    public function getProblem() {
        self::getInstance();
        return $this->problem;
    }

    private function getInstance() {
        if (self::$object == null) {
            self::$object = new MyExceptions();
        }
    }

}
PHP:
MyExceptions::setProblem("habibi",001);

var_dump(MyExceptions::getProblem());

Fatal error: Using $this when not in object context in D:\wamp\www\MyExceptions.php on line 11

Нещо не мога да я схвана тази грешка.
 
За грешката - викаш не-статична функция като статична. И за това нямаш достъп до $this в класа.

За ексепшъните най-добре си организирай така кода, че това дето вика тия habibi() да е в една функция, над която ще боднеш един catch. Ексепшъните "бълбукат" нагоре :lol: и лесно ще я хванеш където ти трябва.
 
StormBreaker каза:
За грешката - викаш не-статична функция като статична. И за това нямаш достъп до $this в класа.

За ексепшъните най-добре си организирай така кода, че това дето вика тия habibi() да е в една функция, над която ще боднеш един catch. Ексепшъните "бълбукат" нагоре :lol: и лесно ще я хванеш където ти трябва.
http://codepad.org/62oQjtWe

За момента до тука съм стигнал.Идеята е ако извикам от някъде контролер,модел,вию или прсото базата данни се прецака да изтрещи това. А не глупавите PHP грешки.
Kакво ще кажеш ? Как ти се струва ?
 
Може да ползваш ticks за да проверява кода.

Пример:

http://codepad.viper-7.com/xSbfwa

П.П. За твоя код, ползвай $this вместо getInstance.
Като го чисти си проверявай с false, нема нужда от цел масив noproblem => noproblem.
 
PHP:
class MyExceptions {

    private static $object = null;
    private $problem = array();

    private function __construct() { }
    private function __clone() { }
    
    public static function getInstance() {
        if (self::$object == null) {
            self::$object = new MyExceptions();
        }
        
        return self::$object;
    }
    
    public function setProblem($msg, $code) {
        $this->problem = array('msg' => $msg, 'code' => $code);
    }

    public function getProblem() {
        return $this->problem;
    }

}

Правиш $object и $problem да са private, защото имаш публични методи, които ще правят промени по тях. Леко се обезмисля съществуването на set и getProblem ако $problem е public, защото всеки отвън ще може да задава каквито иска стойности на $problem.

За да забраниш правенето на инстанции на класа и клонирането му правиш __construct() и __clone() private.

Метода getInstance() го правиш публичен и това той ще отговаря за създаването на само една инстанция на класа и връщането и.

После си правиш публичните методи, които да записват и взимат грешките и после си използваш класа по следния начин:

PHP:
$exc = MyExceptions::getInstance();

$exc->setProblem("habibi",001);
$exc->setProblem("habibibibi",002);
$exc->setProblem("habibihabibi",003);

var_dump($exc->getProblem());
 
Хора какви са тия изпълнения дето се опитвате да правите? Това със списъка с грешките е по-лоша практика и от връщането на false/-1 или PHP Errors

Идеята е ако извикам от някъде контролер,модел,вию или прсото базата данни се прецака да изтрещи това.
Правиш framework или се опитваш да го модифицираш? Защото ако ползваш нещо на готово и ти хвърля стандартните PHP грешки направо го сменяй докато е време.

Ексепшъните са направени точно за това, което ти трябва. Предполагам, че не можеш да си организираш кода така, че да ти е удобно да ги ползваш. Не знам до колко си наясно с тях, но идеята им е като възникне някъде грешка да хвърлиш съответния ексепшън, след което някъде нагоре по call stack-a да я хванеш. Като я хвърлиш кода се прекратява и върви нагоре докато стигне някъде до try ... catch блок, в който бива хваната. Ако не я хванеш никъде отива на най-високо ниво и прекратява целия скрипт.

PHP:
class InvalidParameter extends Exception
{
public $name, $value;

public function __construct($name, $value)
{
$this->name = $name;
$this->value = $value;
}
}
class DatabaseError extends Exception { }

class my_class
{
public function alabala()
{ 
    try
    { 
$this->do_something(); 
    }
     catch (InvalidParameter $e)
    {
// Има сгрешен параметър
// От InvalidParameter обекта можеш да вземеш информация ако си му дал
echo "Невалиден параметър с име" . $e->name . " и стойност " . $e->value;
    }
    catch (DatabaseError $e)
    {
// Има проблем с БД
    }
}

private function do_something()
{
/// Проверка на параметри и ако има грешка
throw new InvalidParameter($ime_na_parametara, $stoinost);

/// Пращане към БД и ако има грешка
throw new DatabaseError(); // Тук е най-добре класа дето ползваш за БД да си хвърля той грешките, пък ти да не се занимаваш с това

 /// Код ако няма грешки никъде
..... // Това няма да се изпълни нещо ако хвърли грешка по-нагоре
}
}

Добра практика е например да имаш на най-високо ниво един try/catch, който да хваща всякакви НЕхванати ексепшъни и да показва грешка от рода на "Нещо лошо се случи". Иначе идеята е да хващаш грешките където можеш да ги поправиш по някакъв начин или да изведеш съобщение и да прекратиш скрипта.

Ако БД се прецака и ползваш нещо подобно на PDO/mysqli то самото ще хвърли ексепшън, който ако не го хванеш сам ще спре скрипта. Но както казах вече най-добре ако не е хванат до най-високото ниво на кода ти да го хванеш и изпишеш някаква обща грешка. Иначе показваш на потребителя цялата информация за грешката.

Друг проблем при PHP за разлика от други езици е, че се намесват и стандартните PHP Errors. Ето с този код можеш PHP грешките и warning-ите да ги обърнеш на exceptions, които се хвърлят от мястото на обикновената грешка:

PHP 5.2
PHP:
set_error_handler(create_function('$a,$b,$c,$d', 'throw new ErrorException($b, 0, $a, $c, $d);'),
E_ERROR | E_WARNING | E_RECOVERABLE_ERROR | E_USER_ERROR | E_USER_WARNING
);

или по-добрия вариант при PHP 5.3
PHP:
set_error_handler(
function($a, $b, $c, $d)
{
	throw new ErrorException($b, 0, $a, $c, $d);
},
E_ERROR | E_WARNING | E_RECOVERABLE_ERROR | E_USER_ERROR | E_USER_WARNING
);
 
Аз много не разбирам въпроса, мислех, че се търси алтернативен начин за ловене на грешки, изведнъж се оказа, че за запазване на грешки в масив, като никъде не се и ползва изключение в кодовете на index.

Иначе послушай StormBreaker, нема смисъл да запазваш грешки в масив, но явно ти не искаш да ловиш реални грешки, а някакви твой 'бележки', от което всъщност нямаш нужда изключения.
 
Тъй като няма какво да правя, а и практиката доста ми изостава и ставаше дума до онзи ден за framework, и реших да напиша нещо мое.В крайна сметка не мога винаги да използвам готовите.
Идеята ми е , в момента който се отваря Controllera да се провери файла дали съществува ,ако - не - да гърми и да спира нататък нещата.
И смятам, че ако използвам стандартният tray - catch няма да е оптимално за това до където съм стигнал.
Оправих правата над $problems, Вкарал съм getInstance във методите защото си представям кода така :

PHP:
class LoadController{

 function load($controler)
{
// nqma takav  controler 
MyExceptions::setProblem('no found controller',001);

}


}


if(MyExceptions.......)
{
die();


}
Load::Controller($controller_name);
Ей така си го представям


Доста голям проблем е и това ,че не мога да го визуализирам в главата си с обикновеният начин.
 
index каза:
И смятам, че ако използвам стандартният tray - catch няма да е оптимално за това до където съм стигнал.

Защо смяташ така? И в какъв смисъл мислиш, че няма да е оптимално? :)
 
Защото поне както се опитвам да го "видя" в главата си става доста по-завъртяно. А аз се стремя - колкото е по-просто , толкова по-малко ядове и проблеми
 
Не си му свикнал просто:

PHP:
class LoadController{

 function load($controler)
{
// nqma takav  controler 
throw new Exception('no found controller',1);

}


}


try
{
Load::Controller($controller_name);
}
catch (Exception $e)
{
die($e->message); // и $e->code
}
 
Благодаря за помощта :)))
StormBreaker каза:
Не си му свикнал просто:

PHP:
class LoadController{

 function load($controler)
{
// nqma takav  controler 
throw new Exception('no found controller',1);

}


}


try
{
Load::Controller($controller_name);
}
catch (Exception $e)
{
die($e->message); // и $e->code
}

Все повече и повече се замислям. И мисля ,че ще успея.Ще вкарам моделите който ще вкарвам в променлива в Core, след което да ги loadvam един по един в цикъл. След като Контолера и моделите са внесени , тогава да вкарвам мина всички Tray-catch и след това създаваме инсанцийте. Мисля ,че ще се получи.
 

Back
Горе