รีสตาร์ทกระบวนการ CLI โดยไม่โหลดส่วนขยาย Xdebug ยกเว้น xdebug.mode=off
เดิมเขียนโดยเป็นส่วนหนึ่งของผู้แต่ง/ผู้แต่ง ปัจจุบันแยกออกมาและทำให้พร้อมใช้งานเป็นไลบรารีแบบสแตนด์อโลน
ลบการสนับสนุนสำหรับเวอร์ชัน PHP เดิมและเพิ่มการประกาศประเภท
การสนับสนุนระยะยาวสำหรับเวอร์ชัน 2 (PHP 5.3.2 - 7.2.4) เป็นไปตามนโยบาย Composer 2.2 LTS
ติดตั้งเวอร์ชันล่าสุดด้วย:
$ composer require composer/xdebug-handler
use Composer XdebugHandler XdebugHandler ;
$ xdebug = new XdebugHandler ( ' myapp ' );
$ xdebug -> check ();
unset( $ xdebug );
ตัวสร้างใช้พารามิเตอร์ตัวเดียว $envPrefix
ซึ่งเป็นตัวพิมพ์ใหญ่และนำหน้าด้วยค่าฐานดีฟอลต์เพื่อสร้างตัวแปรสภาพแวดล้อมที่แตกต่างกันสองตัว ตัวอย่างข้างต้นช่วยให้สามารถใช้:
MYAPP_ALLOW_XDEBUG=1
เพื่อแทนที่การรีสตาร์ทอัตโนมัติและอนุญาต XdebugMYAPP_ORIGINAL_INIS
เพื่อรับตำแหน่งไฟล์ ini ในกระบวนการรีสตาร์ท ไฟล์ ini ชั่วคราวถูกสร้างขึ้นจากไฟล์ ini ที่โหลด (และสแกน) โดยมีการอ้างอิงไปยังส่วนขยาย Xdebug ที่ถูกใส่เครื่องหมายความคิดเห็นไว้ การตั้งค่า ini ปัจจุบันถูกรวมเข้าด้วยกัน เพื่อให้การตั้งค่า ini ส่วนใหญ่ที่ทำบนบรรทัดคำสั่งหรือโดยแอปพลิเคชันรวมอยู่ด้วย (ดูข้อจำกัด)
MYAPP_ALLOW_XDEBUG
ถูกตั้งค่าด้วยข้อมูลภายในเพื่อตั้งค่าสถานะและใช้ในการรีสตาร์ทMYAPP_ALLOW_XDEBUG
ไม่ได้ตั้งค่าดูตัวอย่างสำหรับข้อมูลเพิ่มเติม
การจัดการสัญญาณแบบอะซิงโครนัสจะถูกเปิดใช้งานโดยอัตโนมัติหากมีการโหลดส่วนขยาย pcntl SIGINT
ถูกตั้งค่าเป็น SIG_IGN
ในกระบวนการหลักและกู้คืนเป็น SIG_DFL
ในกระบวนการรีสตาร์ท (หากไม่มีการตั้งค่าตัวจัดการอื่น)
จาก PHP 7.4 บน Windows การจัดการ CTRL+C
และ CTRL+BREAK
จะถูกเปิดใช้งานโดยอัตโนมัติในกระบวนการรีสตาร์ท และจะถูกละเว้นในกระบวนการหลัก
มีบางสิ่งที่ต้องระวังเมื่อทำงานในกระบวนการที่รีสตาร์ท
วิธีการคงที่เหล่านี้ให้ข้อมูลจากกระบวนการปัจจุบัน โดยไม่คำนึงว่าจะรีสตาร์ทหรือไม่ก็ตาม
ส่งกลับอาร์เรย์ของตำแหน่งไฟล์ ini ดั้งเดิม ใช้สิ่งนี้แทนการเรียก php_ini_loaded_file
และ php_ini_scanned_files
ซึ่งจะรายงานค่าที่ไม่ถูกต้องในกระบวนการที่รีสตาร์ท
use Composer XdebugHandler XdebugHandler ;
$ files = XdebugHandler:: getAllIniFiles ();
# $ files [ 0 ] always exists , it could be an empty string
$ loadedIni = array_shift ( $ files );
$ scannedInis = $ files ;
ตำแหน่งเหล่านี้ยังมีอยู่ในตัวแปรสภาพแวดล้อม MYAPP_ORIGINAL_INIS
นี่คือสตริงที่แยกพาธซึ่งประกอบด้วยตำแหน่งที่ส่งคืนจาก php_ini_loaded_file
ซึ่งอาจว่างเปล่า ตามด้วยตำแหน่งที่แยกวิเคราะห์จากการเรียก php_ini_scanned_files
ส่งคืนอาร์เรย์ของการตั้งค่าที่สามารถใช้กับกระบวนการย่อย PHP หรือเป็นค่าว่างหากกระบวนการไม่ได้เริ่มต้นใหม่
use Composer XdebugHandler XdebugHandler ;
$ settings = XdebugHandler:: getRestartSettings ();
/**
* $ settings : array ( if the current process was restarted ,
* or called with the settings from a previous restart ) , or null
*
* ' tmp Ini ' = > the temporary ini file used in the restart ( string )
* ' scanned Inis ' = > if there were any scanned inis ( bool )
* ' scan Dir ' = > the original PHP _ INI _ SCAN _ DIR value ( false |string )
* ' phprc ' = > the original PHPRC value ( false |string )
* ' inis ' = > the original inis from get AllIniFiles ( array )
* ' skipped ' = > the skipped version from get SkippedVersion ( string )
*/
ส่งคืนสตริงเวอร์ชัน Xdebug ที่ถูกข้ามโดยการรีสตาร์ท หรือสตริงว่างหากไม่มีการรีสตาร์ท (หรือ Xdebug ยังคงโหลดอยู่ อาจเกิดจากการรีสตาร์ทคลาสที่ขยายด้วยเหตุผลอื่นนอกเหนือจากการลบ Xdebug)
use Composer XdebugHandler XdebugHandler ;
$ version = XdebugHandler:: getSkippedVersion ();
# $version : ' 3.1 . 1 ' ( for example ) , or an empty string
คืนค่าเป็นจริงหากโหลด Xdebug และกำลังทำงานในโหมดแอ็คทีฟ (หากรองรับโหมด) ส่งคืน false หากไม่ได้โหลด Xdebug หรือกำลังทำงานด้วย xdebug.mode=off
วิธีการเหล่านี้ใช้อินเทอร์เฟซที่คล่องแคล่วและต้องถูกเรียกก่อนเมธอด main check()
เปิดใช้งานเอาต์พุตข้อความสถานะไปยังตัวบันทึก PSR3 ภายนอก ข้อความทั้งหมดจะถูกรายงานด้วยระดับบันทึก DEBUG
หรือ WARNING
ตัวอย่างเช่น (แสดงระดับและข้อความ):
// No restart
DEBUG Checking MYAPP_ALLOW_XDEBUG
DEBUG The Xdebug extension is loaded (3.1.1) xdebug.mode=off
DEBUG No restart (APP_ALLOW_XDEBUG=0) Allowed by xdebug.mode
// Restart overridden
DEBUG Checking MYAPP_ALLOW_XDEBUG
DEBUG The Xdebug extension is loaded (3.1.1) xdebug.mode=coverage,debug,develop
DEBUG No restart (MYAPP_ALLOW_XDEBUG=1)
// Failed restart
DEBUG Checking MYAPP_ALLOW_XDEBUG
DEBUG The Xdebug extension is loaded (3.1.0)
WARNING No restart (Unable to create temp ini file at: ...)
ข้อความสถานะยังสามารถส่งออกด้วย XDEBUG_HANDLER_DEBUG
ดูการแก้ไขปัญหา
ตั้งค่าตำแหน่งของสคริปต์หลักที่จะรันในการรีสตาร์ท สิ่งนี้จำเป็นในกรณีการใช้งานที่เป็นความลับมากขึ้นเท่านั้น หรือหากตำแหน่ง argv[0]
ไม่สามารถเข้าถึงได้ ชื่อสคริปต์ --
รองรับอินพุตมาตรฐาน
กำหนดค่าการรีสตาร์ทโดยใช้การตั้งค่าแบบถาวร เพื่อไม่ให้โหลด Xdebug ในกระบวนการย่อยใดๆ
ใช้วิธีนี้หากแอปพลิเคชันของคุณเรียกใช้กระบวนการย่อย PHP ตั้งแต่หนึ่งกระบวนการขึ้นไป และไม่จำเป็นต้องใช้ส่วนขยาย Xdebug วิธีนี้จะหลีกเลี่ยงค่าใช้จ่ายในการนำกลยุทธ์กระบวนการย่อยไปใช้โดยเฉพาะ
อีกวิธีหนึ่ง สามารถใช้วิธีนี้เพื่อตั้งค่าสภาพแวดล้อม ปลอด Xdebug เริ่มต้นซึ่งสามารถเปลี่ยนแปลงได้หากกระบวนการย่อยต้องการ Xdebug จากนั้นจึงกู้คืนในภายหลัง:
function SubProcessWithXdebug ()
{
$ phpConfig = new Composer XdebugHandler PhpConfig ();
# Set the environment to the original configuration
$ phpConfig -> useOriginal ();
# run the process with Xdebug loaded
. . .
# Restore Xdebug - free environment
$ phpConfig -> usePersistent ();
}
ไลบรารีเสนอสองกลยุทธ์ในการเรียกใช้กระบวนการ PHP ใหม่โดยไม่ต้องโหลด Xdebug โดยใช้การตั้ง ค่ามาตรฐาน หรือการตั้งค่า ถาวร โปรดทราบว่านี่จะมีความสำคัญก็ต่อเมื่อแอปพลิเคชันเรียกใช้กระบวนการย่อย PHP
ใช้ตัวเลือกบรรทัดคำสั่งเพื่อลบ Xdebug ออกจากกระบวนการใหม่เท่านั้น
หากกระบวนการใหม่เรียกกระบวนการย่อย PHP Xdebug จะถูกโหลดในกระบวนการย่อยนั้น (เว้นแต่ว่าจะใช้ xdebug-handler ซึ่งในกรณีนี้จะมีการรีสตาร์ทอีกครั้ง)
นี่เป็นกลยุทธ์เริ่มต้นที่ใช้ในการรีสตาร์ท
ใช้ตัวแปรสภาพแวดล้อมเพื่อลบ Xdebug ออกจากกระบวนการใหม่และคงการตั้งค่าเหล่านี้ไว้กับกระบวนการย่อยใด ๆ
PHP_INI_SCAN_DIR
ถูกตั้งค่าเป็นสตริงว่าง สิ่งนี้เป็นการบอก PHP ไม่ให้สแกนหา inis เพิ่มเติมPHPRC
ถูกตั้งค่าเป็น ini ชั่วคราวหากกระบวนการใหม่เรียกกระบวนการย่อย PHP Xdebug จะไม่ถูกโหลดในกระบวนการย่อยนั้น
กลยุทธ์นี้สามารถใช้ในการรีสตาร์ทโดยการเรียก setPersistent()
คลาสตัวช่วย PhpConfig
ช่วยให้เรียกใช้กระบวนการย่อย PHP ได้ง่าย (ไม่ว่าจะโหลด Xdebug หรือไม่ก็ตาม) ไม่ว่าจะมีการรีสตาร์ทหรือไม่ก็ตาม
แต่ละวิธีจะส่งคืนอาร์เรย์ของตัวเลือก PHP (เพื่อเพิ่มลงในบรรทัดคำสั่ง) และตั้งค่าสภาพแวดล้อมสำหรับกลยุทธ์ที่ต้องการ เมธอด getRestartSettings() ถูกใช้เป็นการภายใน
useOriginal()
- Xdebug จะถูกโหลดในกระบวนการใหม่useStandard()
- Xdebug จะ ไม่ ถูกโหลดในกระบวนการใหม่ - ดูการตั้งค่ามาตรฐานuserPersistent()
- Xdebug จะ ไม่ ถูกโหลดในกระบวนการใหม่ - ดูการตั้งค่าแบบถาวรถ้าไม่มีการรีสตาร์ท อาร์เรย์ตัวเลือกว่างจะถูกส่งกลับ และสภาพแวดล้อมจะไม่เปลี่ยนแปลง
use Composer XdebugHandler PhpConfig ;
$ config = new PhpConfig ;
$ options = $ config -> useOriginal ();
# $options : empty array
# environment : PHPRC and PHP _ INI _ SCAN _ DIR set to original values
$ options = $ config -> useStandard ();
# $options : [ - n , - c , tmp Ini ]
# environment : PHPRC and PHP _ INI _ SCAN _ DIR set to original values
$ options = $ config -> usePersistent ();
# $options : empty array
# environment : PHPRC = tmpIni , PHP_INI_SCAN_DIR = ''
การตั้งค่าสภาพแวดล้อมต่อไปนี้สามารถใช้เพื่อแก้ไขปัญหาการทำงานที่ไม่คาดคิด:
XDEBUG_HANDLER_DEBUG=1
ส่งข้อความสถานะไปที่ STDERR
หากมีการกำหนดไว้ โดยไม่คำนึงถึงตัวบันทึก PSR3 ใดๆ แต่ละข้อความนำหน้า xdebug-handler[pid]
โดยที่ pid คือตัวระบุกระบวนการ
XDEBUG_HANDLER_DEBUG=2
ดังที่กล่าวข้างต้น แต่จะบันทึกไฟล์ ini ชั่วคราวเพิ่มเติมและรายงานตำแหน่งของไฟล์ในข้อความสถานะ
API ถูกกำหนดโดยคลาสและองค์ประกอบที่สามารถเข้าถึงได้ซึ่งไม่ได้ใส่คำอธิบายประกอบเป็น @internal คลาสหลักมีสองวิธีที่ได้รับการป้องกันซึ่งสามารถแทนที่ได้เพื่อให้มีฟังก์ชันเพิ่มเติม:
ตามค่าเริ่มต้น กระบวนการจะรีสตาร์ทหากมีการโหลด Xdebug และไม่ได้ทำงานด้วย xdebug.mode=off
การขยายวิธีการนี้จะทำให้แอปพลิเคชันตัดสินใจได้โดยการส่งคืนค่าบูลีน (หรือเทียบเท่า) โดยจะเรียกเฉพาะเมื่อ MYAPP_ALLOW_XDEBUG
ว่างเปล่า ดังนั้นจะไม่ถูกเรียกในกระบวนการรีสตาร์ท (โดยที่ตัวแปรนี้มีข้อมูลภายใน) หรือหากการรีสตาร์ทถูกแทนที่
โปรดทราบว่าสามารถใช้ตัวตั้งค่า setMainScript() และ setPersistent() ที่นี่ได้ หากจำเป็น
แอปพลิเคชันสามารถขยายสิ่งนี้เพื่อแก้ไขไฟล์ ini ชั่วคราว ตำแหน่งที่กำหนดในคุณสมบัติ tmpIni
การตั้งค่าใหม่สามารถผนวกเข้ากับส่วนท้ายของข้อมูลได้อย่างปลอดภัย ซึ่ง PHP_EOL
จะถูกยกเลิก
พารามิเตอร์ $command
คืออาร์เรย์ของอาร์กิวเมนต์บรรทัดคำสั่งที่ไม่ได้ใช้ Escape ที่จะใช้สำหรับกระบวนการใหม่
parent::restart($command)
อย่าลืมจบด้วย
ตัวอย่างนี้สาธิตสองวิธีในการขยายฟังก์ชันการทำงานพื้นฐาน:
เพื่อหลีกเลี่ยงค่าใช้จ่ายในการปั่นกระบวนการใหม่ การรีสตาร์ทจะถูกข้ามไปหากมีการร้องขอคำสั่งวิธีใช้แบบง่าย
แอปพลิเคชันจำเป็นต้องเข้าถึงการเขียนไฟล์ phar ดังนั้นจึงจะบังคับให้รีสตาร์ทหากตั้ง phar.readonly
ไว้ (ไม่ว่าจะโหลด Xdebug หรือไม่ก็ตาม) และเปลี่ยนค่านี้ในไฟล์ ini ชั่วคราว
use Composer XdebugHandler XdebugHandler ;
use MyApp Command ;
class MyRestarter extends XdebugHandler
{
private $ required ;
protected function requiresRestart ( bool $ default ): bool
{
if (Command:: isHelp ()) {
# No need to disable Xdebug for this
return false ;
}
$ this -> required = ( bool ) ini_get ( ' phar.readonly ' );
return $ this -> required || $ default ;
}
protected function restart ( array $ command ): void
{
if ( $ this -> required ) {
# Add required ini setting to tmp Ini
$ content = file_get_contents ( $ this -> tmpIni );
$ content .= ' phar.readonly=0 ' . PHP_EOL ;
file_put_contents ( $ this -> tmpIni , $ content );
}
parent :: restart ( $ command );
}
}
ไดเร็กทอรี testsApp
มีสคริปต์บรรทัดคำสั่งที่สาธิตการทำงานภายในในสถานการณ์ต่างๆ ดูสคริปต์ทดสอบการทำงาน
composer/xdebug-handler ได้รับอนุญาตภายใต้ใบอนุญาต MIT โปรดดูรายละเอียดในไฟล์ใบอนุญาต