Forum und email

שימוש ב PHP משורת הפקודה

החל מגירסה 4.3.0 PHPתומכת בSAPI (Server Application Programming Interface), חדש שנקרא CLI שפרושו Command Line Interfaceכמו שהשם מרמז המטרה העיקרית של ה-SAPI type , הוא פיתוח אפליקציות של ה- shell (ושולחן העבודה בנוסף) , בעזרת PHP. יש די הרבה הבדלים בין CLI SAPIוSAPI אחרים , שיוסברו בהמשך. שווה להזכיר ש CLIו CGI שונים, למרות שהם חולקים הרבה התנהגויות דומות.

CLI SAPIהוצג לראשונה ב PHP 4.2.0, אבל רק בגירסת ניסוי, וכדי להשתמש בו היה צריך לאפשר אותו בפרוש בעזרת --enable-cli במהלך הריצה. החל מPHP 4.3.0 CLI SAPIהאופציה --enable-cliהיא ברירת מחדל, ולא אופציונאלית. עדיין אפשר לנטרל את היישום ע"י שימוש ב --disable-cli.

קיום ההקבצים הבינאריים של CLI/CGI מיקומם ושמם, תלוי בצורה שבה PHP הותקנה . ברירת המחדל היא שכאשר מריצים את הפקודה make, גם CGI וגם CLI ממוקמים ב sapi/cgi/phpוsapi/cli/php בהתאמה, בתקיית קוד המקור של PHP. אפשר לראות ששניהם נקראיםphp. מה שקורה במשך הביצוע של What happens during make installתלוי בשורת הקונפיגורציה שלך . אם מודול SAPI ספציפי נבחר במשך הקונפיגורציה, , apxs למשל, או שהתכונה --disable-cgiבשימוש, CLI יועתק ל {PREFIX}/bin/phpבתהליך הmake installאחרת ה CGI מונח שם. לדוגמא: אם נכתוב בשורת הפקודה , --with--apxs , אז ה CLI יועתק ל {PREFIX}/bin/phpבמהלךmake install.אם אתה רוצה לרמוס את ההתקנה של ה CGI השתמש ב binary, use make install-cliאחרי make installאו שאתה יכול לציין --disable-cgi בשורת הקונפיגורציה

Note: בגלל ששתי הפקודות --enable-cli ו --enable-cgi מאופשרות כבררת מחדל, לכתוב פשוט --enable-cli בשורת הקונפיגורציה, לא מחייבת בהכרח ש CLI יועתק ל {PREFIX}/bin/php במהלך הmake install.

חבילת ההפצה ל windows , בגרסאות בין PHP 4.2.0 ו PHP 4.2.3 הפיצה את CLI בצורת php-cli.exe, באותה תיקייה כמו CGI php.exe. החל מגירסה PHP 4.3.0, חבילת ההפצה ל windows מפיצה את CLI כקובץ php.exeבתקיה נפרדת בשםcli, כך שcli/php.exe.

Note: איזה SAPI יש לי? ב shell, הקלדת php -v נותנת את התוצאה, אם php היא CGI או CLI. ראה גם את הפונקציה php_sapi_name() והקבוע PHP_SAPI.

Note: ביוניקס נוסף מדריך החל מ PHP 4.3.2, לכן הפקודה man phpתתן את התוצאה המבוקשת.

הבדלים משמעותיים בין CLI SAPIוסוגים אחרים של SAPI.

  • בניגוד לCGI SAPI, שום כותרות , headers, לא נכתבות לפלט.

    למרות ש CGI SAPI מאפשר לנטרל את ה HTTP headers, אין שום אופציה מקבילה, לאפשר אותם בCLI SAPI.

    CLI מותחלת במצב שקט בתור ברירת מחדל , למרות שאפשרות, -q נשמרת בשביל התאמה ל CGI scripts עתיקים.

    Plain text error messages (no HTML formatting).

  • יש כמה הנחיות php.ini מסוימות שנדרסות ע"י CLI SAPIבגלל שאין בהם שום הגיון בסביבת ה shell :

    רמיסת הנחיות של php.ini
    הגדרה CLI SAPIערך ברירת מחדל הערה
    html_errors FALSE עלול להיות די מסובך לקרוא את הוראות השגיאה, מתוך מעטפת ההפעלה, כשהם עטופות בכל אותם תגי HTML , לכן ההגדרה הזאת תשונה ל FALSE.
    implicit_flush TRUE המטרה היא שכל פלטו שמגיע מהפונקציות : print(), echo() ושאר פונקציות הפלט, יוצג על המסך באופן מיידי, ולא יתקע באיזה בפר. אתה עדיין יכול להשתמש בהגדרה, output buffering אם אתה מעוניין לעשות מניפולציות על הפלט הסטנדרטי.
    max_execution_time 0 (unlimited) תוכניות שנכתבו לשימוש ברשת אמורות להתבצע בזמן קצר, בניגוד תכוניות שנכתבו למעטפת ההפעלה, ולכן הזמן המקסימלי לריצה שונה ל-ללא הגבלה.
    register_argc_argv TRUE

    בזכות הקביעה של ההגדרה הזאת לאמת, תמיד תהיה גישה למשתנים, argc (number of arguments passed to the application) ו argv (array of the actual arguments) ב CLI SAPI.

    החל מ PHP 4.3.0, המשתנים $argcו$argvמקבלים את הערכים הנכונים להם .בגירסאות קודמות היווצרות המשתנים האלה ארעה כמו ב CGIוMODULE , שדרשה את שההגדרות של PHP register_globalsיופעלו. בלי קשר תמיד אפשר לגשת ל $_SERVERאו$HTTP_SERVER_VARSלדוגמא:$_SERVER['argv']

    Note: לא ניתן לאתחל את ההגדרות האלה מקובץ php.ini אבל אפשר לשנות את הערכים של ההגדרות בזמן הריצה למשל:register_argc_argv.

  • על מנת להקל על העבודה במסגרת המעטפת , הוגדרו כמה קבועים :

    CLI specific Constants
    קבוע Description
    STDIN stream מוכן ל stdin,שחוסך זמן לפתוח אותו בצורה הבאה,
    $stdin = fopen('php://stdin', 'r');
    STDOUT stream מוכן ל stdout,שחוסך זמן לפתוח אותו בצורה הבאה,
    $stdout = fopen('php://stdout', 'w');
    STDERR stream מוכן ל stderr,שחוסך זמן לפתוח אותו בצורה הבאה,
    $stderr = fopen('php://stderr', 'w');

    לכן אם ברצונך לפתוח stream , ל Given the above, you don't need to open e.g. a stream for stderr , לדוגמא, פשוט השתמש בקבוע שכבר קיים כך:

    php -r 'fwrite(STDERR, "stderr\n");'
    אין צורך לסגור את הקשרים האלה , הם נסיגרים אוטומטית על ידיPHP בסיום רצית הסקריפט.

  • CLI SAPI לא משנה את התיקיה הנוכחית, לתיקיה שבה רץ הסקריפט !

    דומגא שממחישה את ההבדלים בCGI SAPI:

    <?php
        
    /* Our simple test application named test.php*/
        
    echo getcwd(), "\n";
    ?>

    בשימוש בגירסתCGIהפלט הוא :

    $ pwd
    /tmp
    
    $ php -q another_directory/test.php
    /tmp/another_directory
    
    מה שמראה בברור ש PHPמשנה את התיקיה הנוכחית , לאחת מהתיקיות שבה רץ סקריפט כרגע.

    שימוש בCLI SAPI נותן :

    $ pwd
    /tmp
    
    $ php -f another_directory/test.php
    /tmp
    
    מה שמאפשר יותר גמישות בכתיבת כלי מעטפת ב This allows greater flexibility when writing shell tools in PHP.

    Note: CGI SAPI תומך בCLI SAPIבעזרת הפקודה-Cבעת ריצה משורת הפקודה.

רישמת הפקודות שניתנות לשימוש משורת הפקודה על ידי PHP, ניתנת לברור על ידי כתיבת PHPעם הפקודה -h.

Usage: php [options] [-f] <file> [args...]
       php [options] -r <code> [args...]
       php [options] [-- args...]
  -s               Display colour syntax highlighted source.
  -w               Display source with stripped comments and whitespace.
  -f <file>        Parse <file>.
  -v               Version number
  -c <path>|<file> Look for php.ini file in this directory
  -a               Run interactively
  -d foo[=bar]     Define INI entry foo with value 'bar'
  -e               Generate extended information for debugger/profiler
  -z <file>        Load Zend extension <file>.
  -l               Syntax check only (lint)
  -m               Show compiled in modules
  -i               PHP information
  -r <code>        Run PHP <code> without using script tags <?..?>
  -h               This help

  args...          Arguments passed to script. Use -- args when first argument 
                   starts with - or script is read from stdin

ל CLI SAPIיש שלוש דרכים שונות , על מנת לקבל את הקוד של התוכנית שאתה רוצה להריץ:

  1. פשוט להגיד לPHP להריץ קובץ מסוים.

    php my_script.php
    
    php -f my_script.php
    
    בשתי הדרכים , עם שימוש ב -fאו בלעדיו, יופעל הקובץmy_script.php . ניתן לבחור כל קוץ עם כל סיומת, אין חיוב להשתמש בסיומת .php.

  2. להעביר את הקוד לביצוע ישיר משורת הפקודה.

    php -r 'print_r(get_defined_constants());'
    
    נדרשת תשומת לב מיוחד בשימוש במרכאות ובמשתנים של המעטפת.

    Note: ראה בדוגמא, אין שימוש בתגי התחלה וסוף! המתג -rמבטל את הצורך בהם, שימוש בתגים יוביל לטעות קימפול

  3. ביצוע הקוד דרך הקלט הסטנדרטי (stdin).

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

    $ some_application | some_filter | php | sort -u >final_output.txt
    

לא ניתן לשלב את שלושת הדרכים האלו.

אפשר להעביר, מספר בילתי מוגבל של נתונים לסקריפט, (בהתאם למגבלות של המעטפת עצמה) הנתונים ימצאו במערך הגלובלי $argv. האיבר במקום ה- 0 יכיל תמיד את שם הסקריפט, שהוא במקרה של קוד PHP מגיע מהקלט הסטנדרטי או ממתג שורת הפקודה -r. המערך הגלובלי השני$argcיכיל את מספר האלמנטים שהועברו במערך $argv.

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

# This will not execute the given code but will show the PHP usage
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]

# This will pass the '-h' argument to your script and prevent PHP from showing it's usage
$ php -r 'var_dump($argv);' -- -h
array(2) {
  [0]=>
  string(1) "-"
  [1]=>
  string(2) "-h"
}

ישנה דרך נוספת להתשמש בPHP לכתיבת סקריפטים למעטפת. ע"י הוספה לשורה הראשונה של הסקריפט את הביטוי: #!/usr/bin/php. שאחריו יבוא קוד ה PHP כולל תגיות הפתיחה והסגירה של ה PHP .אחרי ששינת את מצב הקובץ ,כך שיהי מותר לך להריץ אותו (למשל chmod +x test) אפשר להריץ את הקובץ שלך כמו כל קובץ מעטפת.

#!/usr/bin/php
<?php
    var_dump
($argv);
?>
נקרא לקובץ test וכעת אנחנו יכולים להריץ אותו כך:
$ chmod 755 test
$ ./test -h -- foo
array(4) {
  [0]=>
  string(6) "./test"
  [1]=>
  string(2) "-h"
  [2]=>
  string(2) "--"
  [3]=>
  string(3) "foo"
}
במקרה כזה , כמו שאפשר לראות בדוגמה, אפשר להתשמש גם בארגומנטים שמתחילים בסימן - בסקריפט.

אופציות שורת הפקודה
אופציה תיאור
-s

הצגת קוד המקור, בצורה צבעונית.

האופציה מייצרת גירסת HTML צבעונית ומודגשת, הישר לפלט הסטדרטי. שים לב שהאופציה לא מיייצרת בלוק של תגי <code> [...] </code> HTML , אבל לא HTML headers.

Note: המתג הזה לא יפעל במקביל למתג -r

-w

מציג את הקוד ללא הערות, ותוי רווח לבנים.

Note: המתג הזה לא יפעל במקביל למתג -r

-f

מוציא לפועל את הקובץ הנתון. המתג הזה מיותר, ניתן לתת את שם הקובץ להרצה בלעדיו..

-v

כותב את גירסת ה PHP, PHP SAPI, ו Zend , לקלט הסטנדרטי. לדוגמא:

$ php -v
PHP 4.3.0 (cli), Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies

-c

המתג משמש לתיאור הנתיב אל הקובץ php.ini או מאפשר יצירת קובץ INI חדש במקום. (הקובץ לא חייב להיקרא php.ini), לדוגמה:

$ php -c /custom/directory/ my_script.php

$ php -c /custom/directory/custom-file.ini my_script.php

-a

הרצת PHP באופן אינטראקטיבי.

-d

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

-d configuration_directive[=value]

דוגמא, (אין צורך לסדר את השורות):

# Omitting the value part will set the given configuration directive to "1"
$ php -d max_execution_time
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"

# Passing an empty value part will set the configuration directive to ""
php -d max_execution_time=
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""

# The configuration directive will be set to anything passed after the '=' character
$  php -d max_execution_time=20
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$  php
        -d max_execution_time=doesntmakesense
        -r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(15) "doesntmakesense"

-e

מייצר מידע נוסף ומורחב, למטרות דיבוג.

-z

מעלה את ההרחבות של Zend. אם ניתן רק שם של קובץ , PHP תנסה להעלות את ההרחבות , מהספריה הנוכחית של המערכת, (בד"כ בלינוקס זו ספריית /etc/ld.so.conf). העברת קובץ + נתיב אבסולוטי, לא ישתמש בחיפוש מערכת לנתיב הספריה. העברת קובץ + נתיב יחסי יגרום ל PHP לנסות להעלות את ההרחבות יחסית לספריה העכשוית.

-l

האופציה בודקת האם בקוד PHPנתון קיימות שגיאות. במקרה ואין שגיאות יכתב No syntax errors detected in <filename> לפלט הסטנדרטי, והקוד שיוחזר מהמעטפת יהיה0. ומקרה שיש שגיאות יכתבErrors parsing <filename>לפלט הסטנדרטי, והקוד שיוחזר מהמעטפת יהיה255.

האופציה לא מוצאת שגיאות קריטיות , למשל (like undefined functions). על מנת לזהות שגיאות כאלה גם צריך להשתמש באופציה -f.

Note: המתג הזה לא יפעל במקביל למתג -r

-m

שימוש באופציה הזאת יגרום ל PHP להדפיס את כל המודלים האינטגרליים שבנויים בה וב ZEND:

$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype

[Zend Modules]

-i הואפציה הזאת קוראת לפונקציה phpinfo(), ומדפיסה את התוצאות. אם PHP לא מתפקדת בצורה הגיונית, עדיף לקרוא לאופציה php -i ולראות איזה הודעות שגיאה נשלחות, בתוך או לפני טבלאות הנתונים. שים לב שהפלט הוא בתצורת HTML ולכן עלול להיות ענקי.
-r

האופציה הזאת מאפשרת ביצוע קוד PHPהישר משורת הפעולה , אין צורך להוסיץף את תגי הפתיחה והסגירה של PHP . (<?php ו ?>) ויגרמו לטעות קימפול, במקרה ויוצגו.

Note: צריך להיזהר לא לגרום התנגשות ,עם הרחבות משתנים שמבצעת המעטפת .
בדוגמה רואים שגיאת קימפול

$ php -r "$foo = get_defined_constants();"
Command line code(1) : Parse error - parse error, unexpected '='
הבעיה פה שהמעטפת sh/bash, מבצעת החלפת משתנים, למרות השימוש במרכאות כפולות ". מאחר והמשתנה $foo לא מוגדר בד"כ, הוא מורחב לכלום ע"י המעטפת sh/bash, והתוצאה שמתקבלת היא כזאת :
$ php -r " = get_defined_constants();"
הדרך הנכונה להעביר את הקוד היא , להשתמש בגרש יחיד '. משתנים במחרוזת עם גרש בודד , אינם מורחבים על ידי המעטפת sh/bash.
$ php -r '$foo = get_defined_constants(); var_dump($foo);'
array(370) {
  ["E_ERROR"]=>
  int(1)
  ["E_WARNING"]=>
  int(2)
  ["E_PARSE"]=>
  int(4)
  ["E_NOTICE"]=>
  int(8)
  ["E_CORE_ERROR"]=>
  [...]
בשימוש במעטפת אחרת מ sh/bash, עלולים להיווצר בעיות אחרות, תרגישו חופשי לשלוח מייל לכתובת , [email protected]. בהחלט אפשר להיתקל בבעיות, כשמנסים להכניס משתנים של המעטפת לתוך הקוד , או בשימוש בתו לוכסן אחורי .

Note: -rאפשרי בCLI SAPI אבל לא בCGI SAPI.

-h בעזרת האופציה הזאת אפשר לקבל תיאור על רשימת האופציות שקיימות ושורת מידע נוספת על דרך פעולתם .

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

Example#1 סקריפט שמיועד להפעלה משורת הפקודה. (script.php)

#!/usr/bin/php
<?php

if ($argc != || in_array($argv[1], array('--help''-help''-h''-?'))) {
?>

This is a command line PHP script with one option.

  Usage:
  <?php echo $argv[0]; ?> <option>

  <option> can be some word you would like
  to print out. With the --help, -help, -h,
  or -? options, you can get this help.

<?php
} else {
    echo 
$argv[1];
}
?>

הוספנו שורה מיוחדת בראשית הסקריפט, שאומרת למערכת שהקובץ צריך להיות מורץ ע"י מפענח של PHP. בגלל שהשתמשנו בגירסה של CLI , לא ישלחו HTTP header לפלט. ניתן להתשמש בשני משתנים בסקריפט, $argc, מספר הארגומנטים +1 (שם הסקריפט), ו $argv, מערך שמכיל את כל הארגומנטים בסקריפט, (כששם הסקריפט נמצא במקום אפס שלו,$argv[0]).

בתוכנית למעלה בדקנו, האם יש יותר מארגומנט אחד או פחות, והאם הארגומנט שישנו הוא, --help, -help, -hאו-?, הדפסנו את הודעת העזרה, הדפסנו את שם הסקריפט בצורה דינאמית. את שאר הארגומנטים אם היו הדפסנו .

בשביל להריץ את הסקריפט ביוניקס ,צריך לתת לו הרשאת ביצוע, ולקרוא לו פשוט כך, script.php echothisאוscript.php -h. בחלונות אפשר להכין קובץ אצווה למשימה הזאת :

Example#2 קובץ אצווה , על מנת להריץ סקריפטים של PHP, משורת הפקודה (script.bat)

@c:\php\cli\php.exe script.php %1 %2 %3 %4
   

בהנחה שקראת לתוכנית למעלה בשם script.php, ויש לך את ה CLI php.exe בתוך c:\php\cli\php.exe קובץ האצווה הזה, יריץ את זה בשבילך ,עם האפשרויות הנוספות: script.bat echothisאוscript.bat -h.

ראה גם מסמכי הרחבה של, Readline לפונקציות נוספות שביכולתך להשתמש, לשפר את תוכניות שורת הפקודה ב PHP.