Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
ErrorException [Warning]: in_array()... when doing a foreach that updates data on database
  • Hello, I am coding a simple application that will do the next: 1. Check for e-mails on a database.
    2. Select all emails that flag_sent is 0.
    3. Foreach of this e-mails, send the e-mail text.
    4. Save if sent. I had problems on the Email class that WanWizard solved on develop: https://github.com/fuel/core/commit/127bffa598d8a8917b10984a5c8251057e35ac57
    Then I pull request another fix for the Email class: https://github.com/fuel/core/pull/252 but this one is not critical, I'll test WITHOUT this. With a fresh clone of branch develop of Fuel. I have a controller Controller_Ajax (because it will be called via ajax, but for now I test outputing on the screen) and two models: Model_Ajax and Model_Camping. Each model extends ORM and I've last develop from a fresh clone too. Controller_Ajax:
    <?php
    class Controller_Ajax extends Controller {
        
        public function action_send()
        {
            $status = Model_Ajax::send_email();
            
            echo json_encode($status);
        }
        
    }
    
    /* End of file ajax.php */
    

    Model_Ajax:
    <?php
    
    class Model_Ajax extends Orm\Model {
        protected static $_observers = array(
            'Orm\Observer_CreatedAt' => array('before_insert'),
            'Orm\Observer_UpdatedAt' => array('before_save'),
        );
    
        public static function send_email()
        {
            $message = "test";
            
            $last_not_sent  = Model_Camping::find()->where("flag_sent", "0")->order_by('id', 'desc')->limit(1)->get_one();
            $emails         = Model_Camping::find()->where("flag_sent", "0")->limit(10);
            
            $emails_total   = $emails->count();
            $emails         = $emails->get();
            
            if(false == $emails)
                return array("message" => "All emails has been sent.", "status" => "1");
            
            $i = 1;
            
            foreach($emails as $recipient)
            {
                $mail = Email::factory(); // I use SMTP on config 
                $mail->to($recipient->email);
                $mail->from("example@domain.tld");
                $mail->subject("FuelTest - Mail $i");
                $mail->message($message);
                
                if(false === $mail->send())
                {
                    echo $mail->print_debugger();
                    
                    return "Error";
                }
                
                $camping = Model_Camping::find($recipient->id);
                
                $camping->flag_sent  = 1;
                $camping->sent_at    = time();
                
                $camping->save();
                
                //$result = DB::update('campings')->value("flag_sent", "1")->where('id', '=', $recipient->id)->execute(); // <- with this happens the same as doing like above
                
                $i++;
            }
            
            if($recipient->id == $last_not_sent->id)
                return array("message" => "All the e-mails has been sent.", "status" => "1");
            else
                return array("message" => "$emails_total emails sent.", "status" => "0");
        }
    }
    
    /* End of file ajax.php */
    

    Camping_model:
    <?php
    
    class Model_Camping extends Orm\Model {
     protected static $_observers = array(
      'Orm\Observer_CreatedAt' => array('before_insert'),
      'Orm\Observer_UpdatedAt' => array('before_save'),
     );
    }
    
    /* End of file campings.php */
    

    When I navigate throw domain.tld/ajax/send happens the next:
    Warning! ErrorException [ Warning ]: in_array() expects parameter 2 to be array, null given OREPATH/classes/error.php @ line 131
    126     * @param   Exception  $e  the exception to show
    127     * @return  void
    128     */
    129    public static function show_php_error(\Exception $e)
    130    {
    131        $fatal = (bool)( ! in_array($e->getCode(), \Config::get('errors.continue_on')));
    132        $data = static::prepare_exception($e, $fatal);
    133
    134        if ($fatal)
    135        {
    136            $data['contents'] = ob_get_contents();
    

    I started debugging to see where is the problem and the first thing I did is debug the \Config::get('errors.continue_on'):
    Variable #1:
    NULL
    
    Variable #1:
    NULL
    

    I get it twice because I've two entries. Then I navigated to classes\database\connection.php, line 61, because is where the config is lost. I placed a Debug::dump($config); on line 61 of this file. Results:
    Variable #1:
    array(6) {
      ["type"]=>
      string(5) "mysql"
      ["connection"]=>
      array(5) {
        ["hostname"]=>
        string(9) "localhost"
        ["database"]=>
        string(6) "vienna"
        ["username"]=>
        string(7) "ipalaus"
        ["password"]=>
        string(7) "soyroot"
        ["persistent"]=>
        bool(false)
      }
      ["table_prefix"]=>
      string(0) ""
      ["charset"]=>
      string(4) "utf8"
      ["caching"]=>
      bool(false)
      ["profiling"]=>
      bool(false)
    }
    
    Variable #1:
    NULL <- so, the database type is lost and Exception throw.
    

    So... this is it. If someone needs more test or my files or whatever needed, please let me know. Or if I'm doing wrong, let me know too. Thank you in advance,
    Isern
  • How I can give more information about this? I first developed this on RC3 and then switched to develop when the email problems. When I had this problems, I only used the specific files (the ones described on this topic) to reproduce the problem... and there is. I can post the database structure (very simple) and you can copy the controller and two models, but I dont like to make you work a lot so... let me know how I can help! Thank you in advance!
  • Have you tried a different approach to the logic and update the database all at once? This code most likely will not scale well, you really shouldn't have an sql query in a foreach loop. Also the email class seems to be set up to send one email at a time, each time you're in the foreach loop you're opening a new SMTP connection which is going to take a while if you have alot of emails and its going to hold up your database connection. But try something like this
    <?php
    
    class Model_Ajax extends Orm\Model {
        protected static $_observers = array(
            'Orm\Observer_CreatedAt' => array('before_insert'),
            'Orm\Observer_UpdatedAt' => array('before_save'),
        );
    
        public static function send_email()
        {
            $message = "test";
            
            $last_not_sent  = Model_Camping::find()->where("flag_sent", "0")->order_by('id', 'desc')->limit(1)->get_one();
            $emails         = Model_Camping::find()->where("flag_sent", "0")->limit(10);
            
            $emails_total   = $emails->count();
            $emails         = $emails->get();
            
            if(false == $emails)
                return array("message" => "All emails has been sent.", "status" => "1");
            
            $i = 1;
    
    //should update all the rows
     $result = DB::update('campings')->value("flag_sent", "1")->where('flag_sent', '=', 0)->execute(); 
            
    //now loop through the array and send an email
            foreach($emails as $recipient)
            {
                $mail = Email::factory(); // I use SMTP on config 
                $mail->to($recipient->email);
                $mail->from("example@domain.tld");
                $mail->subject("FuelTest - Mail $i");
                $mail->message($message);
                
                if(false === $mail->send())
                {
                    echo $mail->print_debugger();
                    
                    return "Error";
                }
                
                $i++;
            }
            
            if($recipient->id == $last_not_sent->id)
                return array("message" => "All the e-mails has been sent.", "status" => "1");
            else
                return array("message" => "$emails_total emails sent.", "status" => "0");
        }
    }
    
  • Hello, I have tried the next:
            $sent = array();
            
            foreach($emails as $recipient)
            &#123;
                $mail = Email::factory();
                $mail->to($recipient->email);
                $mail->from("examle@localhost", "my name");
                $mail->subject("FuelPHP Test - Mail $i");
                $mail->message($message);
                
                if(false === $mail->send())
                &#123;
                    echo $mail->print_debugger();
                    
                    return "Error";
                }
                
                $sent[] = $recipient->id;
                
                $i++;
            }
            
            Debug::dump($sent);
            
            $result = DB::update('campings')->value("flag_sent", "1")->where('id', 'in', $sent)->execute();
    

    Same problem. I use and array to do the update because I need to update only the sent ones!
    ErrorException [ Warning ]: in_array() expects parameter 2 to be array, null given COREPATH/classes/error.php @ line 131
    126     * @param   Exception  $e  the exception to show
    127     * @return  void
    128     */
    129    public static function show_php_error(\Exception $e)
    130    &#123;
    131        $fatal = (bool)( ! in_array($e->getCode(), \Config::get('errors.continue_on')));
    132        $data = static::prepare_exception($e, $fatal);
    133
    134        if ($fatal)
    135        &#123;
    136            $data['contents'] = ob_get_contents();
    

    Thank you in advance
  • You keep on getting config issues, this error happens again because the Config call doesn't return what it should. If it's possible, could you make a zip of your entire fuel directory, and a dump of your database, and send it to my so I can have a look, because I find this very intriguing... You can get it to me via email: wanwizard<at>fuelphp.com.
  • Hello, I have emailed to you. Yes it's, and there is only 2 basic controllers and 2 basic models... it's nothing complicated and nothing touched in core so ... : -/ I wish you can find easily what is this about not only for my for entirely community. Thank you another time for your dedication!! Isern
  • You're running 1.0-RC3. Either you're affected by a bug that was present in that version, or there's something wrong with it. If I replace fuel/core and fuel/packages/orm by the develop version, the issue is solved.
  • Hello, How I can check that I'm on RC-3.0? Because I'm checking out from Github and switching to 'develop' from core and orm... I can check that I'm on develop with core becuase of the change we made the other day but how I can recognize the orm problem? Thank you
    Isern
  • Isern Palaus wrote on Saturday 2nd of July 2011:
    Hello, How I can check that I'm on RC-3.0? Because I'm checking out from Github and switching to 'develop' from core and orm... I can check that I'm on develop with core becuase of the change we made the other day but how I can recognize the orm problem? Thank you
    Isern

    go to the fuel/core and type:
    git branch, it should show smth like:
    * develop
      master
    
    the * means you're on develop also go to packages/orm and type:
    git branch there...
  • Hello huglester, Is what I get...
    ipalaus@tear core % git branch
    * develop
      master
    ipalaus@tear core % cd ../packages/orm 
    ipalaus@tear orm % git branch
    * develop
      master
    ipalaus@tear orm
    

    And ErrorException [ Warning ]: in_array() expects parameter 2 to be array, null given
    COREPATH/classes/error.php @ line 131
    
    126     * @param   Exception  $e  the exception to show
    127     * @return  void
    128     */
    129    public static function show_php_error(\Exception $e)
    130    {
    131        $fatal = (bool)( ! in_array($e->getCode(), \Config::get('errors.continue_on')));
    132        $data = static::prepare_exception($e, $fatal);
    133
    134        if ($fatal)
    135        {
    136            $data['contents'] = ob_get_contents();
    

    Persists... I just repeated the procedure and deleted and cloned a bunch of times. So I'm doing something bad. Thank you
    Isern
  • You have an error elsewhere, that triggers the error in the error class, which in turn causes the original error not to be displayed. Maybe the original error is in your (webserver) log?
  • Line 61 in develop is a blank line. What version of Fuel are you using? And could you http://scrp.at the code of the instance() method in your version of connection.php. Looks like a similar issue like you have with the Email class...
  • Hello WanWizard, Thank you in advance. I'm using develop as you suggested yestaerday. The instance: http://scrp.at/6p I've tried \Config::load('db', true, true); but the problem persists. Thank you in advance. Isern
  • I think there's a different issue here. If you're not using multiple databases, only the default instance ($name = null) is used. Which means that on subsequent calls, the isset() on line 54 will detect that the name belongs to an existing instance, and line 61 will never be reached. If I add your debug on line 61 of a working application, I only get one debug output block. If I add a debug of $name on line 53, I see dozens of debug windows with the text 'development', indicating db.active can be found time and time again. So at the moment, I'm at a loss here...

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion