[Question][Error] Namespace declaration statement has to be the very first statement
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.
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"
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?
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 !
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.
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.
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.