diff --git a/README.md b/README.md
index dd39d501..5d0f270d 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,7 @@ Platform. Please follow the tutorials for instructions on using these samples.
* [Getting started with PHP][getting-started]
* [Authenticating users on PHP][authenticate-users]
+ * [Session handling with PHP][sessions]
## Contributing changes
@@ -20,3 +21,4 @@ Platform. Please follow the tutorials for instructions on using these samples.
[travis-link]: https://travis-ci.org/GoogleCloudPlatform/getting-started-php
[getting-started]: http://cloud.google.com/php/getting-started
[authenticate-users]: http://cloud.google.com/php/getting-started/authenticate-users
+[sessions]: http://cloud.google.com/php/getting-started/sessions
diff --git a/bookshelf/phpunit.xml.dist b/bookshelf/phpunit.xml.dist
index 8c830950..0003b327 100644
--- a/bookshelf/phpunit.xml.dist
+++ b/bookshelf/phpunit.xml.dist
@@ -20,11 +20,6 @@
test
-
-
- ./src
-
-
diff --git a/bookshelf/test/DeployTest.php b/bookshelf/test/DeployTest.php
index 4dc4fe05..e00598a6 100644
--- a/bookshelf/test/DeployTest.php
+++ b/bookshelf/test/DeployTest.php
@@ -20,7 +20,6 @@
use Google\Cloud\TestUtils\FileUtil;
use Google\Cloud\TestUtils\AppEngineDeploymentTrait;
use Google\Cloud\TestUtils\EventuallyConsistentTestTrait;
-use Google\Cloud\TestUtils\TestTrait;
use Google\Cloud\Logging\LoggingClient;
use Google\Cloud\ErrorReporting\V1beta1\ErrorStatsServiceClient;
use Google\Cloud\ErrorReporting\V1beta1\QueryTimeRange;
@@ -32,7 +31,6 @@
*/
class DeployTest extends TestCase
{
- use TestTrait;
use AppEngineDeploymentTrait;
use EventuallyConsistentTestTrait;
diff --git a/sessions/.gitignore b/sessions/.gitignore
new file mode 100644
index 00000000..5049f842
--- /dev/null
+++ b/sessions/.gitignore
@@ -0,0 +1,2 @@
+/vendor
+/.idea
diff --git a/sessions/README.md b/sessions/README.md
new file mode 100644
index 00000000..64db8cba
--- /dev/null
+++ b/sessions/README.md
@@ -0,0 +1,8 @@
+# Session handling with PHP on Google Cloud Platform
+
+This directory contains the complete sample code for session handling with PHP
+using Firestore. Follow the tutorial to run the code:
+
+ * [Session handling with PHP][sessions]
+
+[sessions]: http://cloud.google.com/php/getting-started/sessions
diff --git a/sessions/app.yaml b/sessions/app.yaml
new file mode 100644
index 00000000..71d0ca74
--- /dev/null
+++ b/sessions/app.yaml
@@ -0,0 +1 @@
+runtime: php72
diff --git a/sessions/composer.json b/sessions/composer.json
new file mode 100644
index 00000000..e5979a53
--- /dev/null
+++ b/sessions/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "google/cloud-firestore": "^1.9"
+ }
+}
diff --git a/sessions/index.php b/sessions/index.php
new file mode 100644
index 00000000..3ca55449
--- /dev/null
+++ b/sessions/index.php
@@ -0,0 +1,63 @@
+ $projectId,
+]);
+
+# [START getting_started_sessions_create_handler]
+$handler = $firestore->sessionHandler(['gcLimit' => 500]);
+# [END getting_started_sessions_create_handler]
+
+// Configure PHP to use the the Firebase session handler.
+session_set_save_handler($handler, true);
+session_save_path('sessions');
+session_start();
+# [END getting_started_sessions_register_handler]
+
+# [START getting_started_sessions_front_controller]
+$colors = ['red', 'blue', 'green', 'yellow', 'pink'];
+/**
+ * This is an example of a front controller for a flat file PHP site. Using a
+ * Static list provides security against URL injection by default.
+ */
+switch (@parse_url($_SERVER['REQUEST_URI'])['path']) {
+ case '/':
+ if (!isset($_SESSION['views'])) {
+ $_SESSION['views'] = 0;
+ $_SESSION['color'] = $colors[rand(0, 4)];
+ }
+ printf(
+ 'Views: %s',
+ $_SESSION['color'],
+ $_SESSION['views']++
+ );
+ break;
+ default:
+ http_response_code(404);
+ exit('Not Found');
+ }
+# [END getting_started_sessions_front_controller]
+# [END getting_started_sessions_all]
diff --git a/sessions/php.ini b/sessions/php.ini
new file mode 100644
index 00000000..99c3c4b9
--- /dev/null
+++ b/sessions/php.ini
@@ -0,0 +1,3 @@
+; enable the gRPC extension
+extension=grpc.so
+extension=protobuf.so
diff --git a/sessions/phpunit.xml.dist b/sessions/phpunit.xml.dist
new file mode 100644
index 00000000..82682283
--- /dev/null
+++ b/sessions/phpunit.xml.dist
@@ -0,0 +1,28 @@
+
+
+
+
+
+ test
+
+
+
+
+ ./src
+
+
+
diff --git a/sessions/test/DeployTest.php b/sessions/test/DeployTest.php
new file mode 100644
index 00000000..b83f7582
--- /dev/null
+++ b/sessions/test/DeployTest.php
@@ -0,0 +1,55 @@
+client->get('/');
+ $this->assertEquals('200', $resp->getStatusCode());
+ $this->assertContains('Views: 0', (string) $resp->getBody());
+
+ $resp = $this->client->get('/');
+ $this->assertEquals('200', $resp->getStatusCode());
+ $this->assertContains('Views: 1', (string) $resp->getBody());
+ }
+
+ /**
+ * Set up the client.
+ *
+ * @before
+ */
+ public function setUpClient()
+ {
+ $url = self::$gcloudWrapper->getBaseUrl();
+ $this->client = new Client([
+ 'base_uri' => $url,
+ 'cookies' => true,
+ ]);
+ }
+}