7

在下面的类中,我需要 kill() 来结束类中发生的任何事情,并停止类中的所有进程,而不是脚本:

<?php
class email {
    //Expressions
    const exp_name      = "/^[A-Za-z .'-]+$/";
    const exp_email     = '/^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/';
    const error         = "We are sorry, but there appears to be a problem with the form you submitted.<br/>";
    private $msg        = 'Thank you for subscribing';
    protected $status   = true;


    function __construct() {
        self::validate();
        echo '<br/>the CLASS continued</b><br/>';
    }


    private function validate() {
        //Empty fields
        foreach ($_REQUEST as $key => $value) {
            $val = str_replace( ' ', '', $value );
            if ( $val === '' ) {
                self::error( 'empty', $key );
                self::kill(); //If empty, this should end the loop and class
            } //if:empty
        } //foreach


        //Validate Name
        if( !preg_match(self::exp_name,$_POST['Name']) ) {
            self::error( 'name' );
            self::kill(); //kill


        //Validate e-Mail
        if( !preg_match(self::exp_email,$_POST['e-Mail']) ) {
            self::error( 'email' );
            self::kill(); //kill
        }
  }


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

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


    private function error( $type = null, $value = null ) {
        switch( $type ) {
            case 'empty':
            $this->msg = self::error . "<div class='error'><b>The following field is empty: </b>" . $value . "</div>";
            self::set( false );
            break;

            case 'name':
            $this->msg = self::error . "<div class='error'><b>The First Name you entered does not appear to be valid.</b></div>";
            self::set( false );
            break;

            case 'email':
            $this->msg = self::error . "<div class='error'><b>The e-Mail you entered does not appear to be valid.</b></div>";
            self::set( false );
            break;

            default:
            self::set( false );
            $this->msg = self::error;
        }
    return; //kill app
    }


    private function set( $boolean = false ) {
        $this->status = $boolean;
    }


    private function kill() {
        //die();
        //exit( $this );
        //exit();
        //return;
        //break;
    }
}


$email = new email();
echo $email->msg();
echo '<br/>';
echo '<br/>';
echo 'The script continued!!!';
?>
4

6 回答 6

12

正如上面在评论中回答的那样,尝试使用“try”和“catch”块。

更改“验证”方法

private function valdidate( $type = null, $value = null ) {
    // Anything that is going wrong:
    throw new Exception("Your error message");
}

课外:

try {
      $mail = new email();
} catch (Exception $e) {
      echo $e->getMessage(); // Handle the message properly here.
}

有关异常的更多信息,请参阅:

http://php.net/manual/en/language.exceptions.php

于 2013-02-05T23:46:54.637 回答
2

而不是self::kill();简单地使用return;

如果您需要kill做其他事情,那么只需return self::kill();在需要调用它时使用并更改kill为:

private function kill() {
    doStuff();
    return;
}
于 2013-03-18T16:08:11.923 回答
1

没有人阻止你只返回布尔validate方法,然后设置一个简单的 if/else 块来评估其结果。

private function validate() {
    //Empty fields
    foreach ($_REQUEST as $key => $value) {
        $val = str_replace( ' ', '', $value );
        if ( $val === '' ) {
            // You shouldn't call staticaly 
            // self::error( 'empty', $key );
            $this->error('empty', $key);
            // self::kill(); //If empty, this should end the loop and class
            return false;
        } //if:empty
    } //foreach


    //Validate Name
    if( !preg_match(self::exp_name,$_POST['Name']) ) {
        $this->error( 'name' );
        return false;
    }

    //Validate e-Mail
    if( !preg_match(self::exp_email,$_POST['e-Mail']) ) {
        $this->error( 'email' );
        return false;
    }

    return true;
}

然后在构造函数中:

if ($this->validate()) {
    echo '<br/>the CLASS continued</b><br/>';
}
于 2013-03-19T17:36:13.443 回答
0

您可以像这样以编程方式执行此操作:

class email {
    //Expressions
    public static $errorOccuredInCurrentRun = false;

    const exp_name = "/^[A-Za-z .'-]+$/";
    const exp_email = '/^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/';
    const error = "We are sorry, but there appears to be a problem with the form you submitted.<br/>";

    private $msg = 'Thank you for subscribing';
    protected $status = true;

    public static function factory(){
        //du your validation
        self::$errorOccuredInCurrentRun = false;
        self::validate();
        if(!self::$errorOccuredInCurrentRun){
            return new Email();
        }else{
            return null;
        }
    }

    private function __construct() {
        echo '<br/>the CLASS continued</b><br/>';
    }

    private static function validate() {
        //Empty fields
        foreach ($_REQUEST as $key => $value) {
            if(self::$errorOccuredInCurrentRun){
                break;
            }
            $val = str_replace(' ', '', $value);
            if ($val === '') {
                self::error('empty', $key);
                self::kill(); //If empty, this should end the loop and class
            } //if:empty
        } //foreach
        //Validate Name
        if(self::$errorOccuredInCurrentRun){
            if (!preg_match(self::exp_name, $_POST['Name'])) {
                self::error('name');
                self::kill(); //kill
                //Validate e-Mail
                if(self::$errorOccuredInCurrentRun){
                    if (!preg_match(self::exp_email, $_POST['e-Mail'])) {
                        self::error('email');
                        self::kill(); //kill
                    }
                }
            }
        }
    }

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

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

    private function error($type = null, $value = null) {
        switch ($type) {
            case 'empty':
                $this->msg = self::error . "<div class='error'><b>The following field is empty: </b>" . $value . "</div>";
                self::set(false);
                break;

            case 'name':
                $this->msg = self::error . "<div class='error'><b>The First Name you entered does not appear to be valid.</b></div>";
                self::set(false);
                break;

            case 'email':
                $this->msg = self::error . "<div class='error'><b>The e-Mail you entered does not appear to be valid.</b></div>";
                self::set(false);
                break;

            default:
                self::set(false);
                $this->msg = self::error;
        }
        return; //kill app
    }

    private function set($boolean = false) {
        $this->status = $boolean;
    }

    private function kill() {
        self::$validationRunCompleted;
    }

}

然后像这样使用它:

$email = email::factory();
if(is_null($email)){
    //something went wrong
}else{
    //validation was fine
}

如果当前的“运行”没有任何错误,我只执行东西。并且只有在没有错误的情况下,您才能获得电子邮件对象本身,您可以继续并做您需要的事情

于 2013-03-21T17:28:51.057 回答
0

问题是课堂上没有“杀了我”的选项。PHP 使用unset方法来销毁一个不能从类中调用的变量。正如手册所述“自 PHP 5 以来,无法在对象方法中取消设置 $this。”,因此您无法杀死您的类。

话虽如此,那么您将如何处理它以确保在它不验证时不会发生任何事情?确保检查不应继续出错的类的每个方法中的状态。下面您会发现您的代码已更改以显示此过程。请务必阅读关于我为什么做某事的评论。

<?php
class email {
    //Expressions
    const exp_name      = "/^[A-Za-z .'-]+$/";
    const exp_email     = '/^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/';
    const error         = "We are sorry, but there appears to be a problem with the form you submitted.<br/>";
    private $msg        = 'Thank you for subscribing';
    protected $status   = true;


    function __construct() {
        //first check if it validates.
        //if it doesnt, end the constructor so the "class continued" line won't show.
        if (!self::validate()) {
            return;
        }


        echo '<br/>the CLASS continued</b><br/>';
    }


    private function validate() {
        //have the validate method return true/false.
        //Now you can use the output of this method to stop the script if needed

        //Empty fields
        foreach ($_REQUEST as $key => $value) {
            $val = str_replace( ' ', '', $value );
            if ( $val === '' ) {
                self::error( 'empty', $key );
                return false; //just return false when it doesnt validate
            } //if:empty
        } //foreach


        //Validate Name
        if( !preg_match(self::exp_name,$_POST['Name']) ) {
            self::error( 'name' );
            return false; //just return false when it doesnt validate
        }

        //Validate e-Mail
        if( !preg_match(self::exp_email,$_POST['e-Mail']) ) {
            self::error( 'email' );
            return false; //just return false when it doesnt validate
        }

        //else return true
        return true;
    }

    public function status() {
        //always allow the script to return the status
        return $this->status;
    }

    public function msg() { 
        //always allow the script to return the error message
        return $this->msg;
    }

    //example function on how to make sure nothing happens on error
    public function send() {    
        //return false on error so the rest method is not executed
        if ($this->status!==true)
            return false;

        //else continue
        echo "I'm sending an email!";
        //mail(.....)
    }


    private function error( $type = null, $value = null ) {     
        //you set the status to false here, so you can use it to check if an error occured
        //since you always set it to false, remove it from the switch statement. 
        //This way there is less duplicate code and thus less chance for errors

        self::set( false );

        switch( $type ) {
            case 'empty':
                $this->msg = self::error . "<div class='error'><b>The following field is empty: </b>" . $value . "</div>";
                break;

            case 'name':
                $this->msg = self::error . "<div class='error'><b>The First Name you entered does not appear to be valid.</b></div>";
                break;

            case 'email':
                $this->msg = self::error . "<div class='error'><b>The e-Mail you entered does not appear to be valid.</b></div>";
                break;

            default:
                $this->msg = self::error;
        }

        return;
    }


    private function set( $boolean = false ) {
        //use a check to set the value to make sure its always a boolean
        //this way it will be false unless you actually set it to true.
        $this->status = ($boolean===true);
    }
}


$email = new email();

//now you can do a check for the message and only continue if there was no error
if ($email->status() !== false) {
    //Do whatever you want with the e-mail
    $email->send();
    echo 'An e-mail has been sent!';
} else {
    echo 'Something was wrong with the email ('.$email->msg().')';
}

//or another approach could be to directly send it and catch if there was an error
//make sure to check for false with === to be sure its realy a boolean. 
//If you would just check with == the method would also fail if the send() method would return 0 for instance
if ($email->send() === false) {
    echo 'Something was wrong with the email ('.$email->msg().')';
}

//but no matter what, the script will continue
echo '<br/>';
echo '<br/>';
echo 'And the script continued!!!';
?>
于 2013-03-21T08:20:24.623 回答
0

如果我理解正确,则kill()可以使用return false. 据我所知,return 会将您“抛出”到方法之外,并且执行不会受到任何影响。抱歉,如果我没有正确理解您的问题。

此致!

于 2013-03-20T15:15:09.227 回答