Entorno de ejecución de PHP

El entorno de ejecución de PHP es la pila de software encargada de instalar el código de tu servicio web y sus dependencias, así como de ejecutar tu servicio.

Para especificar PHP en el entorno estándar de App Engine, declara el tiempo de ejecución en el archivo app.yaml. Por ejemplo:

runtime: phpVERSION

Donde VERSION es la versión de PHP MAJOR y MINOR. Por ejemplo, para usar la versión más reciente de PHP, PHP 8.4, especifica 84.

Para ver otras versiones de PHP compatibles y la versión de Ubuntu correspondiente a tu versión de PHP, consulta el calendario de asistencia de tiempo de ejecución.

Versión de PHP

La última versión de PHP compatible es la 8.4. El entorno de ejecución de PHP usa la versión estable más reciente de la versión especificada en el archivo app.yaml. App Engine se actualiza automáticamente a las nuevas versiones de lanzamiento de parches, pero no actualiza automáticamente la versión secundaria.

Por ejemplo, tu aplicación puede implementarse en PHP 7.3.0 y, más adelante, actualizarse automáticamente a la versión 7.3.1, pero no se actualizará automáticamente a PHP 7.4.0.

Inicio de la aplicación

Deberás implementar un controlador principal para gestionar todo el enrutamiento de solicitudes.

En los siguientes ejemplos se muestran diferentes formas de servir tu aplicación:

  • Si tu aplicación contiene un archivo public/index.php o index.php, App Engine usa este archivo para servir tu aplicación.

    Te recomendamos que uses un framework, como Laravel, Symfony o Slim, porque proporciona un enrutamiento ligero para escribir y desplegar aplicaciones PHP rápidamente. Consulta un ejemplo de controlador frontal Slim.

    Sin embargo, si vas a migrar una aplicación antigua, consulta el siguiente archivo index.php de ejemplo para importar los archivos PHP que necesites e implementar el controlador principal manualmente:

    switch (@parse_url($_SERVER['REQUEST_URI'])['path']) {
        case '/':
            require 'homepage.php';
            break;
        case '/contact.php':
            require 'contact.php';
            break;
        default:
            http_response_code(404);
            exit('Not Found');
    }
  • Si especifica el elemento opcional entrypoint en el archivo app.yaml, App Engine usará el comando del elemento entrypoint para publicar su aplicación en lugar de usar public/index.php o index.php:

        entrypoint: serve path/to/my/front/controller.php
    

    El campo entrypoint usa el comando serve integrado, que es un programa de los tiempos de ejecución de PHP que inicia la implementación de php-fpm y un servidor web en segundo plano. Este servidor web enruta todo el tráfico al archivo PHP proporcionado mediante el patrón de diseño del controlador frontal.

    El comando serve tiene dos marcas opcionales:

    • --workers=N: especifica el número N de trabajadores de php-fpm. Si no defines la marca --workers, el comando serve adivina el número de trabajadores en función de la cantidad de memoria disponible. Para obtener los mejores resultados, asigna el mismo número a los valores de la marca --workers en el comando serve y en el elemento max_concurrent_requests.

    • --enable-dynamic-workers: especifica que quieres que los php-fpm trabajadores se generen solo cuando sea necesario. De forma predeterminada, se usa una política estática para los trabajadores de php-fpm. Puedes cambiar el número máximo de trabajadores generados con la marca --workers=N. De forma predeterminada, el número máximo de trabajadores generados es el que se define en la política estática.

    Las marcas opcionales deben ir antes de la ruta del controlador frontal:

        entrypoint: serve --workers=2 --enable-dynamic-workers path/to/index.php
    
  • Para desplegar un proceso de trabajador de larga duración, define el elemento entrypoint en la ruta de archivo del proceso de trabajador:

        entrypoint: php long-running-worker-file.php
    

    Si el elemento entrypoint ejecuta una secuencia de comandos con un proceso de larga duración, como un trabajador de Pub/Sub suscrito a un tema, no uses el comando serve.

Para obtener más información, consulta la referencia de app.yaml .

Extensiones habilitadas

Se han habilitado las siguientes extensiones en los entornos de ejecución de PHP para App Engine:

  • BCMath
  • bz2
  • Calendar
  • core
  • cgi
  • ctype
  • cURL
  • date
  • dba
  • dom
  • enchant
  • Exif
  • fcgi
  • fileinfo
  • filter
  • FTP
  • GD
  • gettext
  • GMP
  • hash
  • iconv
  • intl
  • json
  • LDAP
  • libxml
  • mbstring
  • MYSQLi
  • mysqlnd
  • MySQL (PDO)
  • OPcache
  • OpenSSL
  • PCNTL
  • pcre
  • PDO
  • pgsql
  • Phar
  • posix
  • PostgreSQL (PDO)
  • Reflection
  • session
  • Shmop
  • SimpleXML
  • SOAP
  • Sockets
  • sodium (PHP 8.x only, not available for PHP 7.x)
  • SPL
  • SQLite (PDO)
  • SQLite3
  • standard
  • test
  • tidy
  • tokenizer
  • XML
  • XMLreader
  • XMLrpc (PHP 7.x only, not available for PHP 8.x)
  • XMLwriter
  • XSL
  • zend
  • Zip
  • Zlib

Extensiones cargables dinámicamente

Las siguientes extensiones se pueden cargar de forma dinámica configurando php.ini:

Para habilitar estas extensiones, añada directivas para ellas en el archivo php.ini, en extension. Por ejemplo:

extension=memcached.so
extension=grpc.so
extension=protobuf.so
extension=mongodb.so
extension=imagick.so
extension=opencensus.so
extension=redis.so

[opentelemetry]
extension=opentelemetry.so

Variables de entorno

El tiempo de ejecución define las siguientes variables de entorno:

Variable de entorno Descripción
GAE_APPLICATION El ID de tu aplicación de App Engine. Este ID tiene el prefijo "region code~", como "e~" en el caso de las aplicaciones desplegadas en Europa.
GAE_DEPLOYMENT_ID ID de la implementación actual.
GAE_ENV El entorno de App Engine. Su valor debe ser standard.
GAE_INSTANCE El ID de la instancia en la que se está ejecutando tu servicio.
GAE_MEMORY_MB Cantidad de memoria disponible para el proceso de la aplicación, en MB.
GAE_RUNTIME El tiempo de ejecución especificado en el archivo app.yaml.
GAE_SERVICE El nombre del servicio especificado en el archivo app.yaml. Si no se especifica ningún nombre de servicio, se le asigna el valor default.
GAE_VERSION La etiqueta de la versión actual de tu servicio.
GOOGLE_CLOUD_PROJECT El ID de proyecto Google Cloud asociado a tu aplicación.
PORT El puerto que recibe solicitudes HTTP.
NODE_ENV (solo disponible en el entorno de ejecución de Node.js) Tiene el valor production cuando se implementa el servicio.

Puede definir variables de entorno adicionales en el archivo app.yaml, pero los valores anteriores no se pueden anular, excepto NODE_ENV.

Proxies HTTPS y de reenvío

App Engine finaliza las conexiones HTTPS en el balanceador de carga y reenvía las solicitudes a tu aplicación. Algunas aplicaciones necesitan determinar la IP y el protocolo de la solicitud original. La dirección IP del usuario está disponible en el encabezado estándar X-Forwarded-For. Las aplicaciones que requieran esta información deben configurar su framework web para que confíe en el proxy.

Sistema de archivos

El tiempo de ejecución incluye un directorio /tmp con permiso de escritura, mientras que el resto de los directorios tienen acceso de solo lectura. Escribir en /tmp ocupa memoria del sistema. Para obtener más información, consulta la sección sobre la compatibilidad con tempnam() y sys_get_temp_dir().

Servidor de metadatos

Cada instancia de tu aplicación puede usar el servidor de metadatos de App Engine para consultar información sobre la instancia y tu proyecto.

Puede acceder al servidor de metadatos a través de los siguientes endpoints:

  • http://metadata
  • http://metadata.google.internal

Las solicitudes enviadas al servidor de metadatos deben incluir el encabezado de solicitud Metadata-Flavor: Google. Este encabezado indica que la solicitud se ha enviado para recuperar valores de metadatos.

En la siguiente tabla se enumeran los endpoints en los que puedes hacer solicitudes HTTP para obtener metadatos específicos:

Punto final de metadatos Descripción
/computeMetadata/v1/project/numeric-project-id El número de proyecto asignado a tu proyecto.
/computeMetadata/v1/project/project-id El ID del proyecto asignado a tu proyecto.
/computeMetadata/v1/instance/region Región en la que se ejecuta la instancia.
/computeMetadata/v1/instance/service-accounts/default/aliases
/computeMetadata/v1/instance/service-accounts/default/email La dirección de correo de la cuenta de servicio predeterminada asignada a tu proyecto.
/computeMetadata/v1/instance/service-accounts/default/ Muestra todas las cuentas de servicio predeterminadas de tu proyecto.
/computeMetadata/v1/instance/service-accounts/default/scopes Enumera todos los ámbitos admitidos de las cuentas de servicio predeterminadas.
/computeMetadata/v1/instance/service-accounts/default/token Devuelve el token de autenticación que se puede usar para autenticar tu aplicación en otras APIs de Google Cloud.

Por ejemplo, para obtener tu ID de proyecto, envía una solicitud a http://metadata.google.internal/computeMetadata/v1/project/project-id.

A continuación, se muestra un ejemplo de cómo llamar a los endpoints de metadatos mediante cURL o la biblioteca de cliente de Google Cloud:

/**
 * Requests a key from the Metadata server using the Google Cloud SDK. Install
 * the Google Cloud SDK by running "composer install google/cloud"
 *
 * @param $metadataKey the key for the metadata server
 */
function request_metadata_using_google_cloud($metadataKey)
{
    $metadata = new Google\Cloud\Core\Compute\Metadata();
    $metadataValue = $metadata->get($metadataKey);

    return $metadataValue;
}

/**
 * Requests a key from the Metadata server using cURL.
 *
 * @param $metadataKey the key for the metadata server
 */
function request_metadata_using_curl($metadataKey)
{
    $url = 'http://metadata/computeMetadata/v1/' . $metadataKey;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Metadata-Flavor: Google'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    return curl_exec($ch);
}

Sesiones

PHP proporciona una capa de gestión de sesiones que permite a las aplicaciones web conservar la información del estado del usuario entre solicitudes. Las sesiones de App Engine funcionan de forma muy similar a las de cualquier otra aplicación PHP.

Para definir una variable en la sesión de un usuario, puede usar el siguiente código:

session_start();
$_SESSION['Foo'] = 'Bar';

El siguiente código imprimirá Bar en una solicitud posterior del mismo usuario:

session_start();
print $_SESSION['Foo']; // prints Bar

Para sesiones de mayor duración, usa un servicio de almacenamiento alternativo, como Cloud SQL.

Claves especiales de $_SERVER

PHP pone a disposición la matriz especial $_SERVER[] en el ámbito de la solicitud. Además de los parámetros CGI estándar, App Engine añade algunas claves útiles adicionales:

  • GAE_APPLICATION: ID del proyecto de la aplicación actual. Google Cloud
  • GAE_DEPLOYMENT_ID: ID del código fuente implementado.
  • GAE_ENV: el entorno de App Engine (estándar o flexible) en el que se ejecuta tu aplicación.
  • GAE_INSTANCE: nombre de la instancia que se está ejecutando.
  • GAE_MEMORY_MB: cantidad de memoria disponible para el proceso de la aplicación, en MB.
  • GAE_RUNTIME - El tiempo de ejecución especificado en el archivo app.yaml, como php72.
  • GAE_SERVICE: nombre del servicio implementado actualmente.
  • GAE_VERSION: nombre de la versión implementada.
  • GOOGLE_CLOUD_PROJECT - Google Cloud ID de proyecto.
  • HTTP_X_APPENGINE_CITY: nombre de la ciudad desde la que se ha originado la solicitud. Por ejemplo, una solicitud de la ciudad de Mountain View podría tener el valor "mountain view" en el encabezado.
  • HTTP_X_APPENGINE_CITYLATLONG: latitud y longitud de la ciudad desde la que se ha enviado la solicitud. Esta cadena podría ser "37.386051,-122.083851" en el caso de una solicitud de Mountain View.
  • HTTP_X_APPENGINE_COUNTRY: país desde el que se ha enviado la solicitud, en formato de código de país ISO 3166-1 alfa-2. App Engine determina este código a partir de la dirección IP del cliente.
  • HTTP_X_APPENGINE_HTTPS - Verifica el uso de HTTPS.
  • HTTP_X_APPENGINE_REGION: nombre de la región desde la que se ha originado la solicitud. Este valor solo tiene sentido en el contexto del país en X-Appengine-Country. Por ejemplo, si el país es "US" y la región es "ca", "ca" significa "California", no Canadá.
  • HTTP_X_APPENGINE_USER_IP: dirección IP del cliente. Ten en cuenta que $_SERVER['HTTP_X_APPENGINE_USER_IP'] es la única forma en que tu aplicación puede obtener la dirección IP del cliente. La variable $_SERVER['REMOTE_ADDR'] no está disponible en App Engine.

Directivas con nuevos valores predeterminados de inicialización

En la siguiente tabla se especifican las directivas cuyos valores predeterminados de inicialización difieren de los que se proporcionan con el intérprete estándar de PHP disponible en php.net. Para consultar los valores predeterminados de las directivas que no se especifican en la siguiente tabla, consulta las directivas php.ini.

Directive Valor predeterminado en App Engine
expose_php Off
memory_limit -1
max_execution_time 0
error_reporting E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors Off
display_startup_errors Off
log_errors On
log_errors_max_len 0
ignore_repeated_errors Off
ignore_repeated_source Off
html_errors Off
opcache.enable On
opcache.validate_timestamps Off
opcache.memory_consumption 32

Para anular estas directivas predeterminadas, inclúyelas en un archivo php.ini de tu aplicación.

Compatibilidad con tempnam() y sys_get_temp_dir()

Las aplicaciones de App Engine se ejecutan en un espacio aislado de seguridad en el que solo se puede escribir en el directorio /tmp, que se almacena en la RAM de la instancia. Por este motivo, la versión de App Engine de tempnam() devuelve un archivo temporal en memoria que se puede escribir en una solución de almacenamiento permanente, como los segmentos de Cloud Storage.

A continuación, se muestra un ejemplo de cómo escribir en el archivo temporal en memoria con file_put_contents() y fwrite().

<?php
$dir = sys_get_temp_dir();
$tmp = tempnam($dir, "foo");
file_put_contents($tmp, "hello");
$f = fopen($tmp, "a");
fwrite($f, " world");
fclose($f);
echo file_get_contents($tmp);

El resultado esperado del ejemplo sería el siguiente:

hello world
.

Gestionar dependencias con Composer

Para obtener más información, consulta la página Especificar dependencias.