9 Replies Latest reply on Jul 9, 2013 10:52 PM by TimDietrich

    Serializing FM API result objects

    Malcolm

      Has anyone figured out how to serialise a result from the FM API and get more back than __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] ?

       

      The manual says:
      If you store a serialized object in a session, you have to include the class _before_ you initialize (session_start()) the session.

       

      I'm starting both files with a call to FileMaker.php where the classes and objects are defined then a call to start the session is within fmview.php.

       

       


      require_once 'FileMaker.php';

      require_once 'fmview.php';

       

      That seems like it should be OK but it obviously isn't.

       

      Malcolm

       

      I should add that I can work-around this like so:

       

      $data = $result->getRecords();

      $_SESSION['data'] = serialize($data);

       

      getRecords() returns an ordinary array so it can be unserialized without fuss.

        • 2. Re: Serializing FM API result objects
          Malcolm

          Yes, that manual. The instructions and examples there are usually enough to get me out of the woods but there is still something that I'm not doing right.

           

          My question is really to satisfy my curiosity. I can get and serialise the data set, that's the important bit. Doing that and passing it on means that the next page doesn't have to repeat the query to the database.

          • 3. Re: Serializing FM API result objects
            mbraendle

            Malcom,

             

            your question made me curious.

             

            I've tried out with my test example and found the following:

             

            With regards to which object you serialize, the corresponding class definition must be included as well in the PHP page that does the unserialize. E.g. if you serialize an instance of the FileMaker_Result class (e.g. a $result object), you have to include FileMaker/Result.php as well.

             

            Here an example:

             

            serialize1.php

            <?php
            error_reporting(E_ERROR);
            ini_set('display_errors', 'on');
            include_once('./libs/filemaker/FileMaker.php');
            include_once('fm_config.php');
            
            session_start();
            if (array_key_exists('omit', $_REQUEST)) {
              $omit = true;
            } else {
              $omit = false;
            }
            
            
            $fm = new FileMaker('Katalog',C_FM_HOST,C_FM_USER,C_FM_PASSWORD);
            $compfind = $fm--->newCompoundFindCommand('WWW_Results');
            
            $findrequest1 = $fm->newFindRequest('WWW_Results');
            $findrequest1->addFindCriterion('Urheber','Atkins');
            $compfind->add(1, $findrequest1);
            
            $findrequest2 = $fm->newFindRequest('WWW_Results');
            $findrequest2->addFindCriterion('Titel','==Physical Chemistry');
            $findrequest2->setOmit($omit);
            $compfind->add(2, $findrequest2);
            
            $compfind->setRange(0,1000);
            $result = $compfind->execute();
            
            if (FileMaker::isError($result)) {
              $error_code = $result->getCode();
              header('Content-type: text/xml');
              echo '<?xml version="1.0" encoding="UTF-8"?><books count="0" error="' . $error_code . '"/>';
              die();
            }
            // print_r(serialize($result));
            
            
            $_SESSION['fmresult'] = serialize($result);
            header('Location: serialize2.php', true, 302);
            ?>

            serialize2.php:

            <?php

            session_start();

            error_reporting(E_ERROR);

            ini_set('display_errors', 'on');

            include_once('./libs/filemaker/FileMaker.php');

            include_once('./libs/filemaker/FileMaker/Result.php');

             

            $result = unserialize($_SESSION['fmresult']);

             

            $records = $result->getRecords();

            $count = $result->getFoundSetCount();

            header('Content-type: text/xml');

            echo '<?xml version="1.0" encoding="UTF-8"?>';

            echo '<books count="' . $count . '">';

            foreach ($records as $record) {

              echo '<book title="' . $record->getField('Titel') . '" author="' . $record->getField('Urheber') . '" />';

            }

            echo '</books>';

            ?>

            • 4. Re: Serializing FM API result objects
              Malcolm

              With regards to which object you serialize, the corresponding class definition must be included as well in the PHP page that does the unserialize. E.g. if you serialize an instance of the FileMaker_Result class (e.g. a $result object), you have to include FileMaker/Result.php as well.

               

              Aha! My mistake was that I thought the Result object was being defined in FileMaker.php.

               

              thanks for helping with that,

               

              Malcolm

              • 5. Re: Serializing FM API result objects
                TimDietrich

                Malcom --

                 

                Depending on when you unserialize the Result object, you might run into this error: "The script tried to execute a method or access a property of an incomplete object." If so, you'll need to explicitly load the Result and Record class definitions. For example:

                 

                @require_once ( dirname(__FILE__) . '/../libraries/FileMaker/FileMaker/Result.php' );

                @require_once ( dirname(__FILE__) . '/../libraries/FileMaker/FileMaker/Record.php' );

                 

                I'm using this technique in a FileMaker Web application framework that I'm developing. If you're interested, you can see an example here: http://fmwebframe.com/example-fm-result-caching/

                 

                Hope this helps!

                 

                -- Tim

                • 6. Re: Serializing FM API result objects
                  Mike_Mitchell

                  Thanks for this thread, guys. Very valuable.

                   

                  Mike

                  • 7. Re: Serializing FM API result objects
                    Malcolm

                    Yes, that's the step I was missing. I was calling FileMaker.php instead of the class definition.

                     

                    Your framework looks very promising. It appears as though you are already formalising the sort of methods that I'm just developing.

                     

                    At present I'm only caching data within _SESSION though I can see that there's scope to use file caching.

                     

                    The big advantage that I'm seeing is that the feckless user, switching from one page to the next, only waits for each data set once. After that, the data is pulled from memory. The 1 or 2 second lag when switching pages disappear. Our users have never complained about page load speeds but as the developer who has to hit the page dozens of times in a row I'm pleased.

                     

                    Malcolm

                    • 8. Re: Serializing FM API result objects
                      steve_ssh

                      Malcolm wrote:

                       

                      Your framework looks very promising.

                       

                       

                      +1

                       

                      Tim,

                       

                      Your framework project looks like it is going to be really great.  I look forward to checking it out in the future.

                       

                      Best,

                       

                      -steve

                      • 9. Re: Serializing FM API result objects
                        TimDietrich

                        Steve & Malcolm --

                         

                        Thanks for the positive feedback about FMWebFrame. It's been fun to work on.

                         

                        I completed a few changes to the fraemwork a little while ago. The framework's ExecuteSQL and caching functions are now decoupled, so you can use them individually or in combination. I also added a new example page that shows response times for the ExecuteSQL function both with and without caching.

                         

                        There are a few other features that I'd like to add to the framework. My goal is to roll it out to the community soon -- hopefully at DevCon.

                         

                        Thanks again for the feedback!

                         

                        -- Tim