How to inject Doctrine2 into Thread with Symfnony2 in PHP 7.0.2?

69 Views Asked by At

Previously it worked with the version PHP 5.6.3, pthreads, Symfony2, Doctrine2, MongoDB and everything worked very well. I decided to migrate to PHP 7.0.2, I installed pthreads, I'm still using Symfony2, Doctrine2 and MongoDB, but multi thread processing stopped working.

I have defined the following classes:

   class Formula extends \Worker
   {
        static $document_manager;
        static $elements;

        public function start( int $options = NULL  )
        {
            parent::start(PTHREADS_INHERIT_NONE);
        }

        public function run()
        {
            //Set require Autoload and AppKernel
            require_once __DIR__.'/../../../../app/autoload.php';
            require_once __DIR__.'/../../../../app/AppKernel.php';

            //Creating a new AppKernel with the given environment
            $kernel = new \AppKernel( 'dev', 1 );
            //Loading the Cache and Classes
            $kernel->loadClassCache();
            $kernel->boot();

            //Set document manager
            static::$document_manager = $kernel->getContainer()->get('doctrine_mongodb')->getManager(); 

            static::$elements = static::$document_manager->getRepository('MyBundle:Elements')->findAllActive();

            $elements = array();

            //Creating array of objects type Element
            if ( static::$elements )
            {
                foreach ( static::$elements as $element )
                {
                    $elements[] = new Element( $element );
                }
            }

            if (!empty($elements))
            {
                foreach ( $elements as $element )
                {
                    //For each element execute the run method using start
                    $element->start();
                    $element->join();               
                }
            }       

            $processed_elements = array();

            while ( count($elements) > 0 )
            {
                foreach ( $elements as $id => $element )
                {
                    //If finished the run method
                    if ( !$element->is_running )
                    {
                        $processed_elements[] = $element;
                        //Cleaning up once this thread is done
                        unset($elements[$id]);
                    }
                }
            }

            /**
             * Performing Logic with Processed Items    
             */
        }
    }


    class Element extends \Thread
    {
        public $is_running; 
        static $document_manager;
        static $medicine;

        public function __construct ( $Element )
        {
            error_log( 'Constructing Element Thread' );
            /**
             * Collect item data
             */

            $this->is_running = true;
        }

        public function start(  int $options = Null )
        {
            parent::start(PTHREADS_INHERIT_NONE);
        }   


        public function run()
        {
            //Set require Autoload and AppKernel
            require_once __DIR__.'/../../../../app/autoload.php';
            require_once __DIR__.'/../../../../app/AppKernel.php';

            //Creating a new AppKernel with the given environment
            $kernel = new \AppKernel( 'dev', 1 );
            //Loading the Cache and Classes
            $kernel->loadClassCache();
            $kernel->boot();

            //Set document manager
            static::$document_manager = $kernel->getContainer()->get('doctrine_mongodb')->getManager(); 

            /**
             * Logic for obtaining the medicine ....
             */

            $id_medicamento = 'xxxxxx';
            static::$medicine = static::$document_manager->getRepository('MyBundle:Medicine')->find($id_medicamento);


            $return = false;

            //Save in the database
            if ( $this->save() )
            {
                $return = true;
            }   

            $this->is_running = false;

            return $return;
        }


        protected function save()
        {
            error_log( 'Saving' );
            //Save the data
            if ( !empty(static::$medicine) )
            {
                //Create new instance of Indication
                $indication = new Indication();
                $indication->setName( 'indication name' );
                $indication->setValue( 'indication value' );
                $indication->setDoctor( "doctor's identification" );
                //Persist Indication
                static::$document_manager->persist( $indication );
                //Add new Indication in Medicine
                static::$medicine->addIndicacion( $indication );

                //Create instance of Event
                $event = new Event();
                $event->setAction( 'Setting indication' );
                $event->setDatetime( new \MongoDate() );
                $event->setComment( 'Event comment' );
                //Persist Event
                static::$document_manager->persist( $event );
                //Add new Event in Medicine
                static::$medicine->addEvento( $event );

                // Write in DB
                static::$document_manager->persist( static::$medicine );

                /**
                 * Here the bug is generated and it neither writes the Indication nor the Event 
                 * in the Medication collection, to know which error was generated I put the 
                 * following line between try-catch and the exception is:
                 * "Catchable Fatal Error: Object of class Volatile could not be converted to string"
                 */         
                static::$document_manager->flush();


                return true;
            }

            return false;
        }

    }

The error is in the save method. Any help to solve this error I am very grateful. Even any optimization of the use of Doctrine that is in both Formula and Element threads would be very helpful. Thank you.

1

There are 1 best solutions below

0
Tony Díaz Ramos On

On the line:

$indication-> setValue($ value);

The value that was received was an array and the field is defined as a string in the document. In this case the array is considered a Volatile object and generated the bug "Catchable Fatal Error: Object of class Volatile could not be converted to string"

The solution was:

$indication-> setValue(json_encode ($ value));