functions-framework-php icon indicating copy to clipboard operation
functions-framework-php copied to clipboard

[Question][Error] Namespace declaration statement has to be the very first statement

Open RobinTHOREL opened this issue 3 years ago • 3 comments

Hey,

Since I've updated my php version (7.4.1 -> 7.4.30) I am facing the following error :

/usr/local/bin/docker-compose exec --user www-data middleware ./scripts/run.sh
[Fri Jul  8 15:31:42 2022] PHP 7.4.30 Development Server (http://0.0.0.0:8080) started
[Fri Jul  8 15:31:55 2022] 172.29.0.1:63960 Accepted
[Fri Jul  8 15:31:55 2022] PHP Fatal error:  Namespace declaration statement has to be the very first statement or after any declare call in the script in /app/vendor/bin/router.php on line 12
[Fri Jul  8 15:31:55 2022] 172.29.0.1:63960 Closing

Is there a doc on this issue? I'm pretty sure I'm not the only one having this problem, but I can't find any troubleshooting.

Any help appreciated.

RobinTHOREL avatar Jul 08 '22 15:07 RobinTHOREL

It's don't appear to be a PHP version's issue. Using the vendor/google/cloud-functions-framework/examples/hello/Dockerfile :

none@MacBook-Pro[~/D/w/middleware]:docker build . \                                                                                                                                                             
    -f vendor/google/cloud-functions-framework/examples/hello/Dockerfile \
    -t middleware
[+] Building 2.8s (13/13) FINISHED                                                                                                                                                                                                      
 => [internal] load build definition from Dockerfile                                                                                                                                                                               0.0s
 => => transferring dockerfile: 37B                                                                                                                                                                                                0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                  0.0s
 => => transferring context: 2B                                                                                                                                                                                                    0.0s
 => [internal] load metadata for gcr.io/gae-runtimes/php74:php74_20210216_7_4_15_RC00                                                                                                                                              0.4s
 => FROM docker.io/library/composer:1                                                                                                                                                                                              1.2s
 => => resolve docker.io/library/composer:1                                                                                                                                                                                        1.2s
 => [internal] load build context                                                                                                                                                                                                  0.3s
 => => transferring context: 776.00kB                                                                                                                                                                                              0.3s
 => [stage-0 1/7] FROM gcr.io/gae-runtimes/php74:php74_20210216_7_4_15_RC00@sha256:b7d4aef9e57c17152c2ea9a3fbd04c23687fc93c7254608bdf6e19f14a7c10f3                                                                                0.0s
 => CACHED [stage-0 2/7] WORKDIR /srv/                                                                                                                                                                                             0.0s
 => CACHED [stage-0 3/7] RUN mkdir .googleconfig &&     echo '{"entrypointContents": "serve vendor/bin/router.php"}' > .googleconfig/app_start.json                                                                                0.0s
 => CACHED [stage-0 4/7] COPY composer.* ./                                                                                                                                                                                        0.0s
 => CACHED [stage-0 5/7] COPY --from=composer:1 /usr/bin/composer /usr/local/bin                                                                                                                                                   0.0s
 => CACHED [stage-0 6/7] RUN composer install --no-dev                                                                                                                                                                             0.0s
 => [stage-0 7/7] COPY . .                                                                                                                                                                                                         0.6s
 => exporting to image                                                                                                                                                                                                             0.5s
 => => exporting layers                                                                                                                                                                                                            0.5s
 => => writing image sha256:5cfef36f6906e1cd8a829624d00f5153f33affb22740ae6189c42eaf5725405e                                                                                                                                       0.0s
 => => naming to docker.io/library/translation-middleware                                                                                                                                                                          0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

then when I run the docker run and GET my localhost:8080 :

none@MacBook-Pro[~/D/w/middleware]:docker run -p 8080:8080 -e FUNCTION_TARGET=entryPoint middleware                                                                                                    
[11-Jul-2022 14:37:05] WARNING: [pool app] child 28 said into stderr: "PHP message: PHP Fatal error:  Namespace declaration statement has to be the very first statement or after any declare call in the script in /srv/vendor/bin/router.php on line 12"
2022/07/11 14:37:05 [error] 30#30: *2 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Namespace declaration statement has to be the very first statement or after any declare call in the script in /srv/vendor/bin/router.php on line 12" while reading response header from upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/tmp/google-config/php-fpm.sock:", host: "localhost:8080"

RobinTHOREL avatar Jul 11 '22 14:07 RobinTHOREL

It's appear the first line in /vendor/bin/router.php make the trouble

#!/usr/bin/env php // <-- this line
<?php

/**
 * Proxy PHP file generated by Composer
 *
 * This file includes the referenced bin path (../google/cloud-functions-framework/router.php)
 *
 * @generated
 */

namespace Composer;

$GLOBALS['_composer_bin_dir'] = __DIR__;
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';


include __DIR__ . '/..'.'/google/cloud-functions-framework/router.php';

when I remove this line, it's working. Perhaps, it's obviously not a solution to remove this line from vendor.

Any help?

RobinTHOREL avatar Jul 11 '22 14:07 RobinTHOREL

I have the same error using the demo code, with or without Docker. The only way I found to use use my functions is to remove this line and commit the vendor folder... It's clearly not the ideal, so if there is another solution I would be happy to know it !

loickvirot avatar Sep 22 '22 10:09 loickvirot

I've tried to troubleshoot this issue, without any luck.

My temporary solution was to reference router.php directly:

RUN mkdir .googleconfig && \
    echo '{"entrypointContents": "serve vendor/google/cloud-functions-framework/router.php"}' > .googleconfig/app_start.json

Also, composer install directly in the container worked perfectly, so it looks like something is wrong with the GAE runtime image.

mputkowski avatar Mar 14 '23 13:03 mputkowski

the same issue in PHP 8.2.2 + Composer 2.5.2 remove the first line #!/usr/bin/env php in /vendor/bin/router.php make it work.

comicat-hu avatar Apr 12 '23 03:04 comicat-hu

Composer has an answer for this, seems like FF is improperly using the bin directive in the composer file which is creating a proxy file that loads the original PHP and includes the shebang (since it's expected to be executed as a binary and not a script):

https://github.com/composer/composer/issues/10533

The composer coming from the GCP buildpacks for PHP are 2.1.3 which is before the 2.2.0 cutoff for these proxy files.

So the solution (for local dev) is to change over to using the full path if you have a new composer version:

php -S localhost:8080 vendor/google/cloud-functions-framework/router.php

I'll go update the examples in a PR.

josephlewis42 avatar Sep 26 '23 16:09 josephlewis42