瀏覽代碼

Update PDO session storage to check if any rows are updated when doing a session write. If no rows are udpated when performing a session write it generally means that we have created a new session id somewhere and we have not inserted into the database. This is the case for when calling regenerate_session_id() from the native session storage class. It will update the session id then call sessionWrite() to save the session but since the new session id does not exist in the DB, no rows are updated and any new session attributes such as security tokens are lost.

See http://www.php.net/manual/en/function.session-set-save-handler.php#103055 for more details
michaelwilliams 14 年之前
父節點
當前提交
46b711c4a8
共有 1 個文件被更改,包括 33 次插入7 次删除
  1. 33 7
      src/Symfony/Component/HttpFoundation/SessionStorage/PdoSessionStorage.php

+ 33 - 7
src/Symfony/Component/HttpFoundation/SessionStorage/PdoSessionStorage.php

@@ -15,6 +15,7 @@ namespace Symfony\Component\HttpFoundation\SessionStorage;
  * PdoSessionStorage.
  * PdoSessionStorage.
  *
  *
  * @author Fabien Potencier <fabien@symfony.com>
  * @author Fabien Potencier <fabien@symfony.com>
+ * @author Michael Williams <michael.williams@funsational.com>
  */
  */
 class PdoSessionStorage extends NativeSessionStorage
 class PdoSessionStorage extends NativeSessionStorage
 {
 {
@@ -174,13 +175,7 @@ class PdoSessionStorage extends NativeSessionStorage
             }
             }
 
 
             // session does not exist, create it
             // session does not exist, create it
-            $sql = 'INSERT INTO '.$dbTable.'('.$dbIdCol.', '.$dbDataCol.', '.$dbTimeCol.') VALUES (?, ?, ?)';
-
-            $stmt = $this->db->prepare($sql);
-            $stmt->bindParam(1, $id, \PDO::PARAM_STR);
-            $stmt->bindValue(2, '', \PDO::PARAM_STR);
-            $stmt->bindValue(3, time(), \PDO::PARAM_INT);
-            $stmt->execute();
+            $this->createNewSession($id);
 
 
             return '';
             return '';
         } catch (\PDOException $e) {
         } catch (\PDOException $e) {
@@ -213,10 +208,41 @@ class PdoSessionStorage extends NativeSessionStorage
             $stmt->bindParam(1, $data, \PDO::PARAM_STR);
             $stmt->bindParam(1, $data, \PDO::PARAM_STR);
             $stmt->bindParam(2, $id, \PDO::PARAM_STR);
             $stmt->bindParam(2, $id, \PDO::PARAM_STR);
             $stmt->execute();
             $stmt->execute();
+
+            if (!$stmt->rowCount()) {
+                // No session exists in the database to update. This happens when we have called
+                // session_regenerate_id()
+                $this->createNewSession($id, $data);
+            }
         } catch (\PDOException $e) {
         } catch (\PDOException $e) {
             throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e);
             throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e);
         }
         }
 
 
         return true;
         return true;
     }
     }
+
+    /**
+     * Creates a new session with the given $id and $data
+     *
+     * @param string $id
+     * @param string $data
+     */
+    private function createNewSession($id, $data = '')
+    {
+        // get table/column
+        $dbTable    = $this->options['db_table'];
+        $dbDataCol = $this->options['db_data_col'];
+        $dbIdCol   = $this->options['db_id_col'];
+        $dbTimeCol = $this->options['db_time_col'];
+
+        $sql = 'INSERT INTO '.$dbTable.'('.$dbIdCol.', '.$dbDataCol.', '.$dbTimeCol.') VALUES (?, ?, ?)';
+
+        $stmt = $this->db->prepare($sql);
+        $stmt->bindParam(1, $id, \PDO::PARAM_STR);
+        $stmt->bindValue(2, $data, \PDO::PARAM_STR);
+        $stmt->bindValue(3, time(), \PDO::PARAM_INT);
+        $stmt->execute();
+
+        return true;
+    }
 }
 }