PHP and Sessions

  • ScottG
  • Proficient
  • Proficient
  • ScottG
  • Posts: 477

Post 3+ Months Ago

Ok So this isn't an error or issue It's a more of a inquiry into other peoples thoughts. Since the last issue I had that caused me, well several days of heavy thought, trial and error, and frustration. I'm starting to rethink how I'm going to handle sessions.

In the past I have a file that is included into every page of my php projects called initialize.php The sole role of this file is to setup the session @session_start(); and any classes that are needed through out the project like the database class.

That file looks like
PHP Code: [ Select ]
<?php
 
/**
*   The initialize class starts all of the main classes and
*   sets the site up.
*
*   @Author     William Gaines <sgscott87@gmail.com>
*   @Copyright  2013-2014 indefinite Designs.
*  
*/
 
 
/***********************************/
/*  Start Session                  */
/***********************************/
 
// Start/Continue a session
@session_start();
 
 
/***********************************/
/*  Error Reporting                */
/***********************************/
 
// We want to see our errors
ini_set('display_errors', '1');
 
// Report all except notices
error_reporting(E_ALL ^ E_NOTICE);
 
 
/***********************************/
/*  Includes and Objects           */
/***********************************/
 
// Include the config
require_once('config.php');
 
// General Functions
require_once('general.php');
 
// Start our error class
require_once('class.error.php');
$err = new Error();
 
// Database Authentication File
require_once('dbauth.php');
 
// Start our database object instance (singleton)
require_once('class.db_connect.php');
$db = DBConnection::instance();
 
?>
 
  1. <?php
  2.  
  3. /**
  4. *   The initialize class starts all of the main classes and
  5. *   sets the site up.
  6. *
  7. *   @Author     William Gaines <sgscott87@gmail.com>
  8. *   @Copyright  2013-2014 indefinite Designs.
  9. *  
  10. */
  11.  
  12.  
  13. /***********************************/
  14. /*  Start Session                  */
  15. /***********************************/
  16.  
  17. // Start/Continue a session
  18. @session_start();
  19.  
  20.  
  21. /***********************************/
  22. /*  Error Reporting                */
  23. /***********************************/
  24.  
  25. // We want to see our errors
  26. ini_set('display_errors', '1');
  27.  
  28. // Report all except notices
  29. error_reporting(E_ALL ^ E_NOTICE);
  30.  
  31.  
  32. /***********************************/
  33. /*  Includes and Objects           */
  34. /***********************************/
  35.  
  36. // Include the config
  37. require_once('config.php');
  38.  
  39. // General Functions
  40. require_once('general.php');
  41.  
  42. // Start our error class
  43. require_once('class.error.php');
  44. $err = new Error();
  45.  
  46. // Database Authentication File
  47. require_once('dbauth.php');
  48.  
  49. // Start our database object instance (singleton)
  50. require_once('class.db_connect.php');
  51. $db = DBConnection::instance();
  52.  
  53. ?>
  54.  


A bit of overview with my last issue I had was with ImageMagick(IM) (programming-forum/imagemagick-and-windows-t108116.html for those who want to know the details), but to put it simply I chased down an issue and the call to IM was indeed causing the issue to happen so i was chasing my tail trying to find a fix/alternative for popen(). It wasn't until I really ripped the script to bare bones i discovered the issue, and that being that since i had sessions going when the call to IM was made if the page was refreshed or called again the php script would try to setup the sessions again but it couldn't because the sessions were in use resulting in a session lock this in turn would lockup IM. Closing the php sessions before the IM call and then reopening them after the call was completed resolved this issue.

While reading the article above about PHP Session Locks, has brought me to rethink how I handle sessions. I am thinking about creating a Session class to handle the sessions. The idea being that the file that php writes session info to will always be closed unless you need to add or change sessions. Once the sessions have been setup they can be closed and you will still be able to access the $_SESSION variable.

Take the following test
s1.php This file sets up a custom session variable
PHP Code: [ Select ]
<?php
@session_start();
$_SESSION['my_session'] = 'Yay! It works';
session_write_close();
?>
<br />
<a href="s2.php">Next</a>
 
  1. <?php
  2. @session_start();
  3. $_SESSION['my_session'] = 'Yay! It works';
  4. session_write_close();
  5. ?>
  6. <br />
  7. <a href="s2.php">Next</a>
  8.  


s2.php This file represents a bad attempt since the session was not continued resulting in no Session info
PHP Code: [ Select ]
<?php
echo (!empty($_SESSION['my_session'])) ? $_SESSION['my_session'] : 'Boo! It failed! You Suck Sessions!';
?>
<br />
<a href="s3.php">Next</a>
 
  1. <?php
  2. echo (!empty($_SESSION['my_session'])) ? $_SESSION['my_session'] : 'Boo! It failed! You Suck Sessions!';
  3. ?>
  4. <br />
  5. <a href="s3.php">Next</a>
  6.  


s3.php This file starts/continues the session and then immediately closes the session file which gives us access to the $_SESSION variable.
PHP Code: [ Select ]
<?php
@session_start(); session_write_close();
echo (!empty($_SESSION['my_session'])) ? $_SESSION['my_session'] : 'Boo! It failed! You Suck Sessions!';
?>
<br />
FIN
 
  1. <?php
  2. @session_start(); session_write_close();
  3. echo (!empty($_SESSION['my_session'])) ? $_SESSION['my_session'] : 'Boo! It failed! You Suck Sessions!';
  4. ?>
  5. <br />
  6. FIN
  7.  


So this is the basic idea behind my session class. when the constructor is called it starts and closes the session right away giving you the $_SESSION variable. a important thing to note is that you are NOT able to set any other sessions unless you start the session again. See the example below

PHP Code: [ Select ]
<?php
@session_start();
$_SESSION['my_session'] = 'Yay! It works';
session_write_close();
 
$_SESSION['bad_session'] = 'This will not work!';
 
@session_start();
$_SESSION['good_session'] = 'Yay! Another good session!';
session_write_close();
 
?>
<pre>
<?php
var_dump($_SESSION);
?>
</pre>
<br />
FIN
 
  1. <?php
  2. @session_start();
  3. $_SESSION['my_session'] = 'Yay! It works';
  4. session_write_close();
  5.  
  6. $_SESSION['bad_session'] = 'This will not work!';
  7.  
  8. @session_start();
  9. $_SESSION['good_session'] = 'Yay! Another good session!';
  10. session_write_close();
  11.  
  12. ?>
  13. <pre>
  14. <?php
  15. var_dump($_SESSION);
  16. ?>
  17. </pre>
  18. <br />
  19. FIN
  20.  


So the class I would be making also will be able to add and change session info as well so instead of doing $_SESSION['index'] = 'content'; you would do something like $sess->modify('index', 'content');.

Any thoughts or concerns? What do think of this approach to Sessions? Since this is a very simple class it will most likely be completed before anyone reads this post lol.
  • Anonymous
  • Bot
  • No Avatar
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post 3+ Months Ago

  • ScottG
  • Proficient
  • Proficient
  • ScottG
  • Posts: 477

Post 3+ Months Ago

As stated I have completed the class and am testing it out currently
  • Bigwebmaster
  • Site Admin
  • Site Admin
  • User avatar
  • Posts: 9090
  • Loc: Seattle, WA & Phoenix, AZ

Post 3+ Months Ago

Have you considered completely scrapping using PHPs basic session handler and writing your own so that you can tailor it to your exact needs and avoid the pitfalls that this seems to be causing you?
  • ScottG
  • Proficient
  • Proficient
  • ScottG
  • Posts: 477

Post 3+ Months Ago

I have thought about doing that, but then there would be a lot more processing going on either database or physical files to manage. Most my issues have been resolved by closing the session when not in use which by the link in the other post confirmed the issue.

here is the class i made to handle session and some uses
session class
PHP Code: [ Select ]
<?php
/**
*   This file is the user class. It is used to add edit
*  delete login or anything else that involes the user.
*
*   @Author     William Gaines <sgscott87@gmail.com>
*   @Copyright  2013-2015
*  
*/
 
 
/***********************************/
/*  Initialize                     */
/***********************************/
 
class Session {
   
   // Start up the Session
   function __construct() {
     
      // Setup the session
      $this->start();
      $this->stop();
   
   }
   
   // This function will start the session
   public function start() {
     
      // Start/Continue the session
      (headers_sent()) ? @session_start() : session_start();
     
   }
   
   // This function will stop the session
   public function stop() {
     
      // Write the close of the seesion file and unlock it
      session_write_close();
     
   }
   
   /**
   * Adds/Edits Session info
   *
   * @param string/array $index This variable can be used as a string for the index in the session variable or as an associative array for the index and content
   * @param string/boolean $content This is the content that will be added to the index in the session. This will be false if the $index is an array.
   * @return boolean
   */
   public function modify($index, $content = false) {
     
      // Start Session
      $this->start();
     
      // Check to see if the $index is an array
      if(is_array($index)) {
         
         // Loop the index array
         foreach($index as $key => $value) {
           
            // Add to the Session
            $_SESSION[$key] = $value;
           
         }
         
      } else {
         
         // Add to the Session
         $_SESSION[$index] = $content;
         
      }
     
      // Stop Session
      $this->stop();
     
      // Kick out
      return true;
     
   }
   
   /**
   * Removes session info
   *
   * @param string/array $index This variable can be used as a string for the index in the session variable or as an array of indexs
   * @return boolean
   */
   public function kill($index) {
     
      // Start Session
      $this->start();
   
      // Check to see if the $index is an array
      if(is_array($index)) {
         
         // Loop the index array
         foreach($index as $key => $value) {
           
            // Add to the Session
            unset($_SESSION[$value]);
           
         }
         
      } else {
         
         // Add to the Session
         unset($_SESSION[$index]);
         
      }
     
      // Stop Session
      $this->stop();
     
      // Kick out
      return true;
     
   }
   
   /**
   * Removes ALL session info and reset everything
   *
   * Note: This will cause an error if there is already output on the page before calling the destroy
   * @return boolean
   */
   public function destroy() {
   
      // Kill the variables
      $this->kill($_SESSION);
     
      // Start Session
      $this->start();
     
      // Unset the session
      session_unset();
     
      // Check for headers sent and spit out a better error if they are. This is so that there is only one error that better describes what is going on
      // this will suppress the errors if the headers are sent and spit out nice warnings
      if(headers_sent($filename, $linenum)) {
         
         // Clear cookies
         @setcookie(session_name(),'',0,'/');
         
         // Reset the session id
         @session_regenerate_id();
         
         // Spit out error
         echo "<br /><strong>Warning:</strong> Your session may not be destroyed. You are receiving this warning due to the headers already being sent. This could occur due to output already on the page before the destroy function was called in <strong>$filename</strong> on line <strong>$linenum</strong><br />\n";
         
      } else {
         
         // Clear cookies
         setcookie(session_name(),'',0,'/');
         
         // Reset the session id
         session_regenerate_id();
         
      }
     
      // Stop Session
      $this->stop();
     
      // Kick out
      return true;
     
   }
 
}
 
?>
 
  1. <?php
  2. /**
  3. *   This file is the user class. It is used to add edit
  4. *  delete login or anything else that involes the user.
  5. *
  6. *   @Author     William Gaines <sgscott87@gmail.com>
  7. *   @Copyright  2013-2015
  8. *  
  9. */
  10.  
  11.  
  12. /***********************************/
  13. /*  Initialize                     */
  14. /***********************************/
  15.  
  16. class Session {
  17.    
  18.    // Start up the Session
  19.    function __construct() {
  20.      
  21.       // Setup the session
  22.       $this->start();
  23.       $this->stop();
  24.    
  25.    }
  26.    
  27.    // This function will start the session
  28.    public function start() {
  29.      
  30.       // Start/Continue the session
  31.       (headers_sent()) ? @session_start() : session_start();
  32.      
  33.    }
  34.    
  35.    // This function will stop the session
  36.    public function stop() {
  37.      
  38.       // Write the close of the seesion file and unlock it
  39.       session_write_close();
  40.      
  41.    }
  42.    
  43.    /**
  44.    * Adds/Edits Session info
  45.    *
  46.    * @param string/array $index This variable can be used as a string for the index in the session variable or as an associative array for the index and content
  47.    * @param string/boolean $content This is the content that will be added to the index in the session. This will be false if the $index is an array.
  48.    * @return boolean
  49.    */
  50.    public function modify($index, $content = false) {
  51.      
  52.       // Start Session
  53.       $this->start();
  54.      
  55.       // Check to see if the $index is an array
  56.       if(is_array($index)) {
  57.          
  58.          // Loop the index array
  59.          foreach($index as $key => $value) {
  60.            
  61.             // Add to the Session
  62.             $_SESSION[$key] = $value;
  63.            
  64.          }
  65.          
  66.       } else {
  67.          
  68.          // Add to the Session
  69.          $_SESSION[$index] = $content;
  70.          
  71.       }
  72.      
  73.       // Stop Session
  74.       $this->stop();
  75.      
  76.       // Kick out
  77.       return true;
  78.      
  79.    }
  80.    
  81.    /**
  82.    * Removes session info
  83.    *
  84.    * @param string/array $index This variable can be used as a string for the index in the session variable or as an array of indexs
  85.    * @return boolean
  86.    */
  87.    public function kill($index) {
  88.      
  89.       // Start Session
  90.       $this->start();
  91.    
  92.       // Check to see if the $index is an array
  93.       if(is_array($index)) {
  94.          
  95.          // Loop the index array
  96.          foreach($index as $key => $value) {
  97.            
  98.             // Add to the Session
  99.             unset($_SESSION[$value]);
  100.            
  101.          }
  102.          
  103.       } else {
  104.          
  105.          // Add to the Session
  106.          unset($_SESSION[$index]);
  107.          
  108.       }
  109.      
  110.       // Stop Session
  111.       $this->stop();
  112.      
  113.       // Kick out
  114.       return true;
  115.      
  116.    }
  117.    
  118.    /**
  119.    * Removes ALL session info and reset everything
  120.    *
  121.    * Note: This will cause an error if there is already output on the page before calling the destroy
  122.    * @return boolean
  123.    */
  124.    public function destroy() {
  125.    
  126.       // Kill the variables
  127.       $this->kill($_SESSION);
  128.      
  129.       // Start Session
  130.       $this->start();
  131.      
  132.       // Unset the session
  133.       session_unset();
  134.      
  135.       // Check for headers sent and spit out a better error if they are. This is so that there is only one error that better describes what is going on
  136.       // this will suppress the errors if the headers are sent and spit out nice warnings
  137.       if(headers_sent($filename, $linenum)) {
  138.          
  139.          // Clear cookies
  140.          @setcookie(session_name(),'',0,'/');
  141.          
  142.          // Reset the session id
  143.          @session_regenerate_id();
  144.          
  145.          // Spit out error
  146.          echo "<br /><strong>Warning:</strong> Your session may not be destroyed. You are receiving this warning due to the headers already being sent. This could occur due to output already on the page before the destroy function was called in <strong>$filename</strong> on line <strong>$linenum</strong><br />\n";
  147.          
  148.       } else {
  149.          
  150.          // Clear cookies
  151.          setcookie(session_name(),'',0,'/');
  152.          
  153.          // Reset the session id
  154.          session_regenerate_id();
  155.          
  156.       }
  157.      
  158.       // Stop Session
  159.       $this->stop();
  160.      
  161.       // Kick out
  162.       return true;
  163.      
  164.    }
  165.  
  166. }
  167.  
  168. ?>
  169.  


test 1
PHP Code: [ Select ]
<?php
 
require_once('cms/classes/class.session.php');
$session = new Session();
 
$session->modify('first_test', 'Yay! It works');
 
// Make an array for sessions
$test_array = array(
            "first_test" => '1 I think you\'ve won!',
            "second_test" => '2 you belong in a zoo!',
            "third_test" => '3 your just like me!',
            "forth_test" => '4 get off the floor!',
            "fith_test" => '5 ... Umm your starting to jive?',
            "sixth_test" => '6 pickup those sticks!'            
            );
 
$session->modify($test_array);
 
?>
<pre>
<?php
var_dump($_SESSION);
?>
</pre>
<br />
<a href="s2.php">Next</a>
 
  1. <?php
  2.  
  3. require_once('cms/classes/class.session.php');
  4. $session = new Session();
  5.  
  6. $session->modify('first_test', 'Yay! It works');
  7.  
  8. // Make an array for sessions
  9. $test_array = array(
  10.             "first_test" => '1 I think you\'ve won!',
  11.             "second_test" => '2 you belong in a zoo!',
  12.             "third_test" => '3 your just like me!',
  13.             "forth_test" => '4 get off the floor!',
  14.             "fith_test" => '5 ... Umm your starting to jive?',
  15.             "sixth_test" => '6 pickup those sticks!'            
  16.             );
  17.  
  18. $session->modify($test_array);
  19.  
  20. ?>
  21. <pre>
  22. <?php
  23. var_dump($_SESSION);
  24. ?>
  25. </pre>
  26. <br />
  27. <a href="s2.php">Next</a>
  28.  


test 2
PHP Code: [ Select ]
 
<?php
 
require_once('cms/classes/class.session.php');
$session = new Session();
 
?>
<pre>
<?php
var_dump($_SESSION);
?>
</pre>
<?php
 
echo 'What about removing Sessions?';
 
$session->kill('second_test');
 
$session->kill(array('forth_test', 'fith_test'));
?>
<pre>
<?php
var_dump($_SESSION);
?>
</pre>
<br />
<a href="s2.php">Refresh</a> <a href="s3.php">Next</a>
 
  1.  
  2. <?php
  3.  
  4. require_once('cms/classes/class.session.php');
  5. $session = new Session();
  6.  
  7. ?>
  8. <pre>
  9. <?php
  10. var_dump($_SESSION);
  11. ?>
  12. </pre>
  13. <?php
  14.  
  15. echo 'What about removing Sessions?';
  16.  
  17. $session->kill('second_test');
  18.  
  19. $session->kill(array('forth_test', 'fith_test'));
  20. ?>
  21. <pre>
  22. <?php
  23. var_dump($_SESSION);
  24. ?>
  25. </pre>
  26. <br />
  27. <a href="s2.php">Refresh</a> <a href="s3.php">Next</a>
  28.  


test 3
PHP Code: [ Select ]
<?php
 
require_once('cms/classes/class.session.php');
$session = new Session();
 
// Please Note that before trying to destroy the sessions you CANNOT have any output before this call.
// This call is to destroy and rest the session info. This would happen mostly on a logout page.
$session->destroy();
echo 'What about Destroying Sessions?';
 
?>
<pre>
<?php
var_dump($_SESSION);
?>
</pre>
<br />
<a href="s4.php">Next</a>
 
  1. <?php
  2.  
  3. require_once('cms/classes/class.session.php');
  4. $session = new Session();
  5.  
  6. // Please Note that before trying to destroy the sessions you CANNOT have any output before this call.
  7. // This call is to destroy and rest the session info. This would happen mostly on a logout page.
  8. $session->destroy();
  9. echo 'What about Destroying Sessions?';
  10.  
  11. ?>
  12. <pre>
  13. <?php
  14. var_dump($_SESSION);
  15. ?>
  16. </pre>
  17. <br />
  18. <a href="s4.php">Next</a>
  19.  


test 4
PHP Code: [ Select ]
<?php
 
require_once('cms/classes/class.session.php');
$session = new Session();
 
?>
 
So you need to do something with the sessions that's not in this class?
<br />
<?php
$session->start();
// Do your stuff here
$session->stop();
?>
<br />
<br />
FIN
 
  1. <?php
  2.  
  3. require_once('cms/classes/class.session.php');
  4. $session = new Session();
  5.  
  6. ?>
  7.  
  8. So you need to do something with the sessions that's not in this class?
  9. <br />
  10. <?php
  11. $session->start();
  12. // Do your stuff here
  13. $session->stop();
  14. ?>
  15. <br />
  16. <br />
  17. FIN
  18.  

Post Information

  • Total Posts in this topic: 4 posts
  • Users browsing this forum: No registered users and 103 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.