Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 3 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ different environments, including:
The framework allows you to go from:

```php
function helloHttp()
use Psr\Http\Message\ServerRequestInterface;

function helloHttp(ServerRequestInterface $request)
{
return "Hello World from a PHP HTTP function!" . PHP_EOL;
}
Expand Down Expand Up @@ -235,26 +237,6 @@ You can configure the Functions Framework using the environment variables shown
| `FUNCTION_SOURCE` | The name of the file containing the source code for your function to load. Default: **`index.php`** (if it exists)
| `FUNCTION_SIGNATURE_TYPE` | The signature used when writing your function. Controls unmarshalling rules and determines which arguments are used to invoke your function. Can be either `http`, `event`, or `cloudevent`. Default: **`http`**

# Enable Background Events

The Functions Framework can unmarshall incoming event payloads to `data` and
`context` objects. These will be passed as arguments to your function when it
receives a request. Note that your function must use the event-style function
signature:

```php
function helloEvents($data, $context)
{
var_dump($data);
var_dump($context);
}
```

To enable automatic unmarshalling, set the `FUNCTION_SIGNATURE_TYPE` environment
variable to `event`. For more details on this signature type, check out the Google Cloud Functions
documentation on
[background functions](https://cloud.google.com/functions/docs/writing/background#cloud_pubsub_example).

# Enable CloudEvents

The Functions Framework can unmarshall incoming [CloudEvents](http://cloudevents.io)
Expand Down
37 changes: 25 additions & 12 deletions src/FunctionWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,34 @@ private function validateFunctionSignature(
ReflectionFunctionAbstract $reflection
) {
$parameters = $reflection->getParameters();
if (count($parameters) != 1) {
throw new LogicException(
'Wrong number of parameters to your function, must be exactly 1'
);
// Check there is at least one parameter
if (count($parameters) < 1) {
$this->throwInvalidFunctionException();
}

$class = $this->getFunctionParameterClassName();
// Check the first parameter has the proper typehint
$type = $parameters[0]->getType();
$class = $this->getFunctionParameterClassName();
if (!$type || $type->getName() !== $class) {
throw new LogicException(
sprintf(
'Your function must have "%s" as the typehint for the first argument',
$class
)
);
$this->throwInvalidFunctionException();
}

if (count($parameters) > 1) {
for ($i = 1; $i < count($parameters); $i++) {
if (!$parameters[$i]->isOptional()) {
throw new LogicException(
'If your function accepts more than one parameter the '
. 'additional parameters must be optional'
);
}
}
}
}

private function throwInvalidFunctionException()
{
throw new LogicException(sprintf(
'Your function must have "%s" as the typehint for the first argument',
$this->getFunctionParameterClassName()
));
}
}
12 changes: 9 additions & 3 deletions tests/CloudEventFunctionsWrapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function testNoFunctionParameters()
{
$this->expectException('LogicException');
$this->expectExceptionMessage(
'Wrong number of parameters to your function, must be exactly 1'
'Your function must have "Google\CloudFunctions\CloudEvent" as the typehint for the first argument'
);
$request = new ServerRequest('POST', '/', []);
$cloudEventFunctionWrapper = new CloudEventFunctionWrapper(
Expand All @@ -71,10 +71,10 @@ public function testTooManyFunctionParameters()
{
$this->expectException('LogicException');
$this->expectExceptionMessage(
'Wrong number of parameters to your function, must be exactly 1'
'If your function accepts more than one parameter the additional parameters must be optional'
);
$cloudEventFunctionWrapper = new CloudEventFunctionWrapper(
function ($foo, $bar) {
function (CloudEvent $foo, $bar) {
}
);
}
Expand Down Expand Up @@ -117,6 +117,12 @@ function (CloudEvent $foo = null) {
}
);
$this->assertTrue(true, 'No exception was thrown');
// additional optional parameters are ok
$cloudEventFunctionWrapper = new CloudEventFunctionWrapper(
function (CloudEvent $foo, $bar = null) {
}
);
$this->assertTrue(true, 'No exception was thrown');
}

public function testWithFullCloudEvent()
Expand Down
12 changes: 9 additions & 3 deletions tests/HttpFunctionWrapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function testNoFunctionParameters()
{
$this->expectException('LogicException');
$this->expectExceptionMessage(
'Wrong number of parameters to your function, must be exactly 1'
'Your function must have "Psr\Http\Message\ServerRequestInterface" as the typehint for the first argument'
);
$request = new ServerRequest('POST', '/', []);
$httpFunctionWrapper = new HttpFunctionWrapper(
Expand All @@ -44,10 +44,10 @@ public function testTooManyFunctionParameters()
{
$this->expectException('LogicException');
$this->expectExceptionMessage(
'Wrong number of parameters to your function, must be exactly 1'
'If your function accepts more than one parameter the additional parameters must be optional'
);
$httpFunctionWrapper = new HttpFunctionWrapper(
function ($foo, $bar) {
function (ServerRequestInterface $foo, $bar) {
}
);
}
Expand Down Expand Up @@ -90,6 +90,12 @@ function (ServerRequestInterface $foo = null) {
}
);
$this->assertTrue(true, 'No exception was thrown');
// additional optional parameters are ok
$httpFunctionWrapper = new HttpFunctionWrapper(
function (ServerRequestInterface $foo, $bar = null) {
}
);
$this->assertTrue(true, 'No exception was thrown');
}

public function testHttpHttpFunctionWrapper()
Expand Down
4 changes: 2 additions & 2 deletions tests/exampleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ class exampleTest extends TestCase

public static function setUpBeforeClass(): void
{
if ('true' === getenv('TRAVIS')) {
self::markTestSkipped('These tests do not pass on travis');
if ('true' === getenv('SKIP_EXAMPLE_TESTS')) {
self::markTestSkipped('Explicitly skipping the example tests');
}

$exampleDir = __DIR__ . '/../examples/hello';
Expand Down
4 changes: 3 additions & 1 deletion tests/fixtures/absolute.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

function helloDefault()
use Psr\Http\Message\ServerRequestInterface;

function helloDefault(ServerRequestInterface $request)
{
return "Hello Absolute!";
}
4 changes: 3 additions & 1 deletion tests/fixtures/index.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

function helloDefault()
use Psr\Http\Message\ServerRequestInterface;

function helloDefault(ServerRequestInterface $request)
{
return "Hello Default!";
}
4 changes: 3 additions & 1 deletion tests/fixtures/relative.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

function helloDefault()
use Psr\Http\Message\ServerRequestInterface;

function helloDefault(ServerRequestInterface $request)
{
return "Hello Relative!";
}
5 changes: 3 additions & 2 deletions tests/vendorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ class vendorTest extends TestCase

public static function setUpBeforeClass(): void
{
if ('true' === getenv('TRAVIS')) {
self::markTestSkipped('These tests do not pass on travis');
if ('true' === getenv('SKIP_EXAMPLE_TESTS')) {
self::markTestSkipped('Explicitly skipping the example tests');
}

mkdir($tmpDir = sys_get_temp_dir() . '/ff-php-test-' . rand());
chdir($tmpDir);

Expand Down