סביבת זמן ריצה של PHP

סביבת הריצה של PHP היא מחסנית התוכנה שאחראית להתקנת הקוד של שירות האינטרנט והתלות שלו ולהפעלת השירות.

כדי לציין PHP עבור הסביבה הרגילה של App Engine, צריך להצהיר על זמן הריצה בקובץ app.yaml. לדוגמה:

runtime: phpVERSION

VERSION הוא מספר הגרסה של PHP MAJOR ו-MINOR. לדוגמה, כדי להשתמש בגרסה האחרונה של PHP, ‏ PHP 8.5, מציינים 85.

לגרסאות נתמכות אחרות של PHP ולגרסת Ubuntu התואמת לגרסת ה-PHP שלכם, אפשר לעיין בלוח הזמנים של התמיכה בזמן ריצה.

גרסת PHP

הגרסה העדכנית ביותר של PHP שנתמכת היא 8.5. סביבת הריצה של PHP משתמשת בגרסה היציבה העדכנית ביותר שצוינה בקובץ app.yaml. ‫App Engine מתעדכן אוטומטית לגרסאות חדשות של תיקוני באגים, אבל לא מתעדכן אוטומטית לגרסאות משניות.

לדוגמה, יכול להיות שהאפליקציה שלכם נפרסה ב-PHP 7.3.0 ומעלה, והיא תעודכן אוטומטית לגרסה 7.3.1, אבל היא לא תעודכן אוטומטית ל-PHP 7.4.0.

הפעלת האפליקציה

תצטרכו לפרוס בקר קדמי כדי לטפל בכל ניתוב הבקשות.

בדוגמאות הבאות מוצגות דרכים שונות להצגת האפליקציה:

  • אם האפליקציה מכילה קובץ public/index.php או index.php,‏ App Engine משתמשת בקובץ הזה כדי להציג את האפליקציה.

    מומלץ להשתמש ב-framework כמו Laravel,‏ Symfony או Slim, כי הוא מספק ניתוב קל משקל לכתיבה ולפריסה מהירה של אפליקציות PHP. דוגמה לבקר קדמי דק

    עם זאת, אם אתם מעבירים אפליקציה מדור קודם, תוכלו להיעזר בקובץ index.php לדוגמה שבהמשך כדי לייבא את קובצי ה-PHP שאתם צריכים ולהטמיע את בקר הקצה באופן ידני:

    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');
    }
  • אם מציינים את הרכיב האופציונלי entrypoint בקובץ app.yaml,‏ App Engine משתמש בפקודה שברכיב entrypoint כדי להציג את האפליקציה במקום להשתמש בפקודות public/index.php או index.php:

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

    השדה entrypoint משתמש בפקודה המובנית serve, שהיא תוכנית בסביבות הריצה של PHP שמפעילה את ההטמעה של php-fpm ושרת אינטרנט ברקע. שרת האינטרנט הזה מעביר את כל התנועה לקובץ ה-PHP שצוין באמצעות דפוס העיצוב של בקר קדמי.

    לפקודה serve יש שני דגלים אופציונליים:

    • --workers=N: מציין את מספר העובדים php-fpm. אם לא מגדירים את הדגל --workers, הפקודה serve מנחשת את מספר העובדים על סמך כמות הזיכרון שזמינה. כדי לקבל את התוצאות הטובות ביותר, צריך להגדיר את הערכים של הדגל --workers בפקודה serve ושל הרכיב max_concurrent_requests כך שיהיו זהים.

    • --enable-dynamic-workers: מציין שרוצים שהתהליכים של php-fpm יופעלו רק לפי הצורך. ברירת המחדל היא שימוש במדיניות סטטית עבור העובדים של php-fpm. אפשר לשנות את המספר המקסימלי של תהליכי worker שנוצרו באמצעות הדגל --workers=N. כברירת מחדל, המספר המקסימלי של תהליכי worker שנוצרים הוא המספר שמוגדר במדיניות הסטטית.

    הדגלים האופציונליים צריכים להופיע לפני הנתיב של בקר הקצה:

        entrypoint: serve --workers=2 --enable-dynamic-workers path/to/index.php
    
  • כדי לפרוס תהליך עובד שפועל לאורך זמן, מגדירים את הרכיב entrypoint לנתיב הקובץ של תהליך העובד:

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

    אם רכיב entrypoint מריץ סקריפט עם תהליך ממושך, כמו Pub/Sub Worker שרשום לנושא, אל תשתמשו בפקודה serve.

מידע נוסף זמין במאמר בנושא app.yaml .

תוספים מופעלים

התוספים הבאים הופעלו בסביבות זמן הריצה של PHP ב-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

תוספים שאפשר לטעון באופן דינמי

אפשר לטעון את התוספים הבאים באופן דינמי על ידי הגדרת php.ini:

כדי להפעיל את התוספים האלה, צריך להוסיף להם הנחיות בקובץ php.ini מתחת ל-extension, לדוגמה:

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

משתני סביבה

משתני הסביבה הבאים מוגדרים על ידי זמן הריצה:

משתנה הסביבה תיאור
GAE_APPLICATION המזהה של אפליקציית App Engine. המזהה הזה מתחיל בקידומת region code~, למשל e~ לאפליקציות שמוצבות באירופה.
GAE_DEPLOYMENT_ID המזהה של הפריסה הנוכחית.
GAE_ENV סביבת App Engine. ההגדרה היא standard.
GAE_INSTANCE המזהה של המופע שבו השירות שלכם פועל כרגע.
GAE_MEMORY_MB נפח הזיכרון שזמין לתהליך האפליקציה, ב-MB.
GAE_RUNTIME סביבת זמן הריצה שצוינה בקובץ app.yaml.
GAE_SERVICE שם השירות שצוין בקובץ app.yaml. אם לא מצוין שם שירות, ברירת המחדל היא default.
GAE_VERSION תווית הגרסה הנוכחית של השירות.
GOOGLE_CLOUD_PROJECT מזהה הפרויקט ב- Google Cloud שמשויך לאפליקציה.
PORT היציאה שמקבלת בקשות HTTP.
NODE_ENV (זמין רק בסביבת זמן ריצה של Node.js) מגדירים את הערך production כשהשירות נפרס.

אפשר להגדיר משתני סביבה נוספים בקובץ app.yaml, אבל אי אפשר לשנות את הערכים שלמעלה, למעט NODE_ENV.

פרוטוקול HTTPS ושרתי proxy להעברה

‫App Engine מפסיק חיבורי HTTPS במאזן העומסים ומעביר בקשות לאפליקציה. באפליקציות מסוימות צריך לקבוע את כתובת ה-IP והפרוטוקול של הבקשה המקורית. כתובת ה-IP של המשתמש זמינה בכותרת הרגילה X-Forwarded-For. באפליקציות שנדרש בהן המידע הזה, צריך להגדיר את מסגרת האינטרנט כך שתיתן אמון ב-proxy.

מערכת קבצים

סביבת זמן הריצה כוללת ספרייה /tmp עם הרשאת כתיבה, ולכל שאר הספריות יש הרשאת קריאה בלבד. כתיבה ל-/tmp תופסת זיכרון מערכת. מידע נוסף זמין במאמרים בנושא תמיכה ב-tempnam() ותמיכה ב-sys_get_temp_dir().

שרת מטא-נתונים

כל מופע של האפליקציה יכול להשתמש בשרת המטא-נתונים של App Engine כדי לשלוח שאילתות לגבי המופע והפרויקט.

אפשר לגשת לשרת המטא-נתונים דרך נקודות הקצה הבאות:

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

בקשות שנשלחות לשרת המטא-נתונים חייבות לכלול את כותרת הבקשה Metadata-Flavor: Google. הכותרת הזו מציינת שהבקשה נשלחה בכוונה מפורשת לאחזר ערכי מטא-נתונים.

בטבלה הבאה מפורטות נקודות הקצה שאליהן אפשר לשלוח בקשות HTTP למטא-נתונים ספציפיים:

נקודת קצה של מטא-נתונים תיאור
/computeMetadata/v1/project/numeric-project-id מספר הפרויקט שהוקצה לפרויקט שלכם.
/computeMetadata/v1/project/project-id מזהה הפרויקט שהוקצה לפרויקט.
/computeMetadata/v1/instance/region האזור שבו המכונה פועלת.
/computeMetadata/v1/instance/service-accounts/default/aliases
/computeMetadata/v1/instance/service-accounts/default/email כתובת האימייל של חשבון השירות שמוגדר כברירת מחדל ומוקצה לפרויקט.
/computeMetadata/v1/instance/service-accounts/default/ מציגה את כל חשבונות השירות שמוגדרים כברירת מחדל בפרויקט.
/computeMetadata/v1/instance/service-accounts/default/scopes רשימה של כל ההיקפים הנתמכים בחשבונות שירות שמוגדרים כברירת מחדל.
/computeMetadata/v1/instance/service-accounts/default/token מחזירה את אסימון האימות שאפשר להשתמש בו כדי לאמת את האפליקציה שלכם ב-Google Cloud APIs אחרים.

לדוגמה, כדי לאחזר את מזהה הפרויקט, שולחים בקשה אל http://metadata.google.internal/computeMetadata/v1/project/project-id.

בדוגמה הבאה מוצגות דרכים לקרוא לנקודות הקצה של המטא-נתונים באמצעות cURL או ספריית הלקוח של 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);
}

סשנים

‫PHP מספקת שכבת ניהול סשנים שמאפשרת לאפליקציות אינטרנט לשמור מידע על מצב המשתמש בין בקשות. סשנים ב-App Engine פועלים בדומה לסשנים בכל אפליקציית PHP אחרת.

כדי להגדיר משתנה בביקור של משתמש, אפשר להשתמש בקוד הבא:

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

הקוד הבא ידפיס Bar, בבקשה הבאה של אותו משתמש:

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

למשכי הפעלה ארוכים יותר, כדאי להשתמש בשירות אחסון חלופי כמו Cloud SQL.

מפתחות מיוחדים של $_SERVER

ב-PHP, המערך המיוחד $_SERVER[] זמין בהיקף הבקשה. בנוסף לפרמטרים הרגילים של CGI, ‏ App Engine מוסיף כמה מפתחות שימושיים:

  • GAE_APPLICATION – מזהה הפרויקט של האפליקציה הנוכחית. Google Cloud
  • GAE_DEPLOYMENT_ID – המזהה של קוד המקור שפרסתם.
  • GAE_ENV – סביבת App Engine (סטנדרטית או גמישה) שבה האפליקציה פועלת.
  • GAE_INSTANCE – השם של המופע שמופעל כרגע.
  • GAE_MEMORY_MB – נפח הזיכרון שזמין לתהליך האפליקציה, ב-MB.
  • GAE_RUNTIME – זמן הריצה שצוין בקובץ app.yaml, למשל php72.
  • GAE_SERVICE – שם השירות שמוטמע כרגע.
  • GAE_VERSION – שם הגרסה שבפריסה כרגע.
  • GOOGLE_CLOUD_PROJECT - Google Cloud מזהה הפרויקט.
  • HTTP_X_APPENGINE_CITY – שם העיר שממנה נשלחה הבקשה. לדוגמה, בקשה מהעיר מאונטיין ויו יכולה לכלול את הכותרת value mountain view.
  • HTTP_X_APPENGINE_CITYLATLONG – קו הרוחב וקו האורך של העיר שממנה נשלחה הבקשה. מחרוזת כזו יכולה להיראות כך: ‎ "37.386051,-122.083851"‎ לבקשה מ-Mountain View.
  • HTTP_X_APPENGINE_COUNTRY – המדינה שממנה נשלחה הבקשה, כקוד מדינה בתקן ISO 3166-1 alpha-2. מערכת App Engine קובעת את הקוד הזה מכתובת ה-IP של הלקוח.
  • HTTP_X_APPENGINE_HTTPS – אימות השימוש ב-HTTPS.
  • HTTP_X_APPENGINE_REGION – שם האזור שממנו הגיעה הבקשה. הערך הזה רלוונטי רק בהקשר של המדינה שצוינה במאפיין X-Appengine-Country. לדוגמה, אם המדינה היא "US" והאזור הוא "ca", האזור "ca" מציין את קליפורניה ולא את קנדה.
  • HTTP_X_APPENGINE_USER_IP – כתובת ה-IP של הלקוח. שימו לב שזו הדרך היחידה שבה האפליקציה יכולה לאחזר את כתובת ה-IP של הלקוח.$_SERVER['HTTP_X_APPENGINE_USER_IP'] המשתנה $_SERVER['REMOTE_ADDR'] לא זמין ב-App Engine.

הוראות עם ערכי ברירת מחדל חדשים לאתחול

בטבלה הבאה מפורטות הנחיות שערכי ברירת המחדל שלהן שונים מאלה שמופיעים במפרש ה-PHP הרגיל שזמין בכתובת php.net. כדי למצוא את ערכי ברירת המחדל של הנחיות שלא מפורטות בטבלה הבאה, אפשר לעיין בהנחיות php.ini.

הוראה ערך ברירת המחדל ב-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

כדי לשנות את ההגדרות של ההוראות האלה שמוגדרות כברירת מחדל, צריך לכלול אותן בקובץ php.ini של האפליקציה.

tempnam() ותמיכה ב-sys_get_temp_dir()

אפליקציות של App Engine פועלות בארגז חול לאבטחה שבו רק ספריית /tmp ניתנת לכתיבה ונשמרת בזיכרון ה-RAM של המופע. לכן, הגרסה של tempnam() ב-App Engine מחזירה קובץ זמני בזיכרון שאפשר לכתוב בו פתרון אחסון קבוע כמו קטגוריות של Cloud Storage.

דוגמה לאופן הכתיבה לקובץ זמני בזיכרון באמצעות file_put_contents() ו-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);

הפלט הצפוי מהדוגמה יהיה:

hello world

ניהול יחסי תלות באמצעות Composer

מידע נוסף זמין במאמר ציון יחסי תלות.