PHP: نوشتن برنامه های خط فرمان با Macrame. Pt 1

PHP به عنوان یک زبان اسکریپت خط فرمان مورد توجه زیادی قرار نمی گیرد. این شرم آور است ، زیرا PHP دارای ویژگی های زیادی است که آن را برای نوشتن برنامه های ترمینال انتخاب خوبی می کند.
در این سری ، ما با استفاده از کتابخانه Macrame ، نوشتن اسکریپت های خط فرمان تعاملی را خواهیم نوشت. ما از طریق ساختن یک پروژه مثال ، اسکریپتی که لیستی از پیروان کاربر Mastodon را از ابتدا تا انتها بدست می آورد ، کار خواهیم کرد و موضوعاتی از قبیل دریافت و اعتبارسنجی ورودی کاربر ، ساختن منوهای تعاملی ، دسترسی به آرگومان های خط فرمان ، دسترسی را پوشش می دهیم. پرونده ها با خیال راحت ، متن خروجی یک ظاهر طراحی شده و اجرای توابع در پس زمینه در حالی که به کاربران ما یک اسپینر متحرک نشان می دهد.
اطلاعات بیشتر در مورد Macrame را می توان در سایت اسناد یافت.
پروژه نمونه
پروژه ای که ما از طریق آن کار خواهیم کرد ، یک اسکریپت خط فرمان ساده است که لیستی از پیروان کاربر Mastodon را برمی گرداند. دویدن به نظر می رسد این:
کاربر نمونه Mastodon مورد نظر را از یک منوی پویا انتخاب می کند ، به عنوان متن رایگان وارد نام کاربری می شود و اسکریپت هنگام واکشی داده ها یک اسپینر متحرک را نشان می دهد. خروجی یک جدول زیبا و به سبک ASCII است.
کد منبع کامل این پروژه برای هر کسی که می خواهد جلوتر باشد ، به عنوان یک مهم است.
پرواز
در این قسط ، ما به این نتیجه خواهیم رسید که:
- macrame را نصب کنید
- داربست یک فیلمنامه خالی
- استدلال های خط فرمان را بخوانید
- یک منوی پویا ایجاد کنید
- یک خط ورودی کاربر را بخوانید (با اعتبار سنجی اختیاری)
- متن خروجی یک ظاهر طراحی شده
macrame را نصب کنید
Macrame از طریق آهنگساز نصب می شود
composer require gbhorwood/macrame
داربست فیلمنامه شما
پس از نصب Macrame ، می توانیم یک اسکریپت اساسی “Hello World” را تنظیم کنیم و از آن به عنوان دیگ بخار شروع کنیم. اگرچه این داربست است از نظر فنی لازم نیست ، استفاده از آن اسکریپت ما را کمی ایمن تر و سازگار تر می کند. بیایید به کد نگاه کنیم:
#!/usr/bin/env php
require __DIR__ . '/vendor/autoload.php';
use Gbhorwood\Macrame\Macrame;
// Instantiate a Macrame object.
// The argument is the name of the script as seen by ps(1)
$macrame = new Macrame("Example Macrame script");
// Enforce that the script only runs if executed on the command line
if($macrame->running()) {
// Validate that the host system can run Macrame scripts. Exit on failure
$macrame->preflight();
// output text to STDOUT
$macrame->text("hello world")->write();
// exit cleanly
$macrame->exit();
}
اگرچه این خطوط زیادی نیست ، اما در اینجا اتفاقات زیادی رخ می دهد. بیایید بیش از آن برویم.
#!/usr/bin/env php
این خط “shebang” است. در اصل ، این سیستم عامل شبیه به لینوکس ما را می گوید که مترجم برای اجرای این اسکریپت از آن استفاده می کند. این به ما امکان می دهد بدون نیاز به تایپ ، اسکریپت خود را اجرا کنیم php
اول Shebang باید حتی قبل از خط اول در پرونده باشید .
$macrame = new Macrame("Example Macrame script");
در اینجا ، ما ایجاد می کنیم Macrame
شیء که ما در تمام بقیه فیلمنامه خود استفاده خواهیم کرد. چیزهای بسیار استاندارد تنها بخش جالب استدلال است. این نامی است که سیستم عامل به اسکریپت ما می دهد. به عنوان مثال ، اگر اجرا کنیم ps
برای نشان دادن لیستی از فرآیندهای در حال اجرا ، اسکریپت ما با این نام نمایش داده می شود.
if($macrame->running())
این بیانیه تضمین می کند که تمام کد داخل بلوک فقط در صورت اجرای اسکریپت در خط فرمان اجرا می شود.
$macrame->preflight();
وقتی PHP را برای خط فرمان می نویسیم ، ما به همان اندازه کنترل محیط را که در یک وب سرور انجام می دهیم و مدیریت می کنیم ، کنترل نمی کنیم. در preflight()
با اینجا تماس بگیرید محیط محلی PHP را آزمایش می کند و اگر حداقل شرایط را برآورده نکند ، اسکریپت را با یک پیام خطا خاتمه می دهد. حداقل نیازها عبارتند از:
- PHP 7.4
-
posix
گسترش -
mbstring
گسترش
توجه: اگرچه Macrame در PHP 7.4 و 8.0 اجرا می شود ، به دلیل تغییر در نحوه کنترل PHP رشته های چند بیت در 8.1 ، رشته های حاوی ایموجی ها ممکن است به درستی در خروجی در PHP قبل از 8.1 تراز نشوند.
$macrame->exit();
این اسکریپت را به صورت تمیز خارج می کند ، و یک کد موفقیت را باز می گرداند 0
بشر علاوه بر این ، هر پرونده موقت ایجاد شده در هنگام اجرای به طور خودکار حذف می شود. با استفاده از macrame exit()
عملکرد برای PHP ارجح است die()
؛
دویدن سلام جهان
هنگامی که اسکریپت اصلی “Hello World” خود را نوشتیم ، می توانیم مجوزهای آن را تنظیم کنیم تا اجازه اجرای آن را بدهیم و آن را در خط فرمان اجرا کنیم.
chmod 755 ./examplescript.php
./examplescript.php
استدلال خواندن
Macrame مجموعه ای از ابزارها را برای تجزیه و تحلیل آرگومان های خط فرمان ارائه می دهد. بیایید با چیزی ساده شروع کنیم: دریافت شماره نسخه هنگامی که اسکریپت با آن فراخوانی می شود:
./examplescript.php --version
# or
./examplescript.php -v
برای این مورد ، تنها کاری که باید انجام دهیم این است که بررسی کنیم که آیا هر یک از این استدلال ها وجود دارد یا خیر.
ما می توانیم این کار را با تماس با args()
روش در ما macrame
شیء ، که یک شیء حاوی تمام آرگومان های اسکریپت ما و مجموعه ای از روش هایی را که می توانیم برای بازرسی از آنها استفاده کنیم ، برمی گرداند. برای آزمایش اگر یک استدلال وجود داشته باشد ، می توانیم از آن استفاده کنیم exists()
روش مانند:
if ($macrame->args('v')->exists() || $macrame->args('version')->exists()) {
$macrame->text('1.0')->write(); // output the version number
$macrame->exit();
}
در exists()
روش یک بولی را برمی گرداند.
call تماس های Macrame به گونه ای طراحی شده اند که زنجیر شوند.
آرگومان های خط فرمان همچنین می توانند برای اختصاص مقادیر به متغیرها استفاده شوند. به عنوان مثال ، برای تنظیم username
ارزش ، ما احتمالاً می خواهیم کاربران ما بتوانند اسکریپت را اینگونه صدا کنند:
./examplescript.php --username=ghorwood
برای به دست آوردن ارزش این استدلال ، در اسکریپت ما می توانیم از first()
روش ارائه شده توسط args()
مانند بنابراین:
$username = $macrame->args('username')->first();
همانطور که از نام پیدا می کند ، first()
روش ارزش را برمی گرداند اولی وقوع استدلال ما. اگر فیلمنامه خود را اینگونه صدا کردیم:
./examplescript.php --username=firstuser --username=seconduser
پس first()
مقدار “FirstUser” را برمی گرداند. اگر آخرین مقدار را می خواهیم ، می توانیم تماس بگیریم last()
بشر اگر می خواهیم همه مقادیر به عنوان یک آرایه ، ما استفاده می کنیم all()
بشر
با هم قرار دادن این همه ، فیلمنامه ما اکنون به این شکل است:
#!/usr/bin/env php
require __DIR__ . '/vendor/autoload.php';
use Gbhorwood\Macrame\Macrame;
$macrame = new Macrame("Example Macrame script");
if($macrame->running()) {
$macrame->preflight();
/**
* Handle the -v or --version arguments
*/
if ($macrame->args('v')->exists() || $macrame->args('version')->exists()) {
$macrame->text('1.0')->write();
$macrame->exit();
}
/**
* Accept first value of --instance=
*/
$instance = $macrame->args('instance')->first();
/**
* Accept first value of --username=
*/
$username = $macrame->args('username')->first();
$macrame->exit();
}
لیست کامل روشهای کنترل خط فرمان در مستندات Macrame در آرگومان ها پوشش داده شده است
ما همچنین می خواهیم به کاربران خود این گزینه را بدهیم که از اسکریپت ما به صورت تعاملی استفاده کنند. اگر آنها آرگومان را در خط فرمان تصویب نکنند ، ما آنها را وادار می کنیم تا داده ها را وارد کنند. برای مقدار نمونه Mastodon ، ما قصد داریم از منو استفاده کنیم.
منوهای Macrame پویا هستند. کاربران ما با استفاده از کلیدهای فلش برای حرکت به بالا یا پایین لیست ، آنها را ساده لوح می کنند و سپس ضربه می زنند
برای انتخاب آنها بیایید تابعی را بنویسیم که منو را به کاربر نشان می دهد و مقدار انتخاب شده را برمی گرداند:
function menuInstance(Macrame $macrame): string
{
$header = "Select your instance";
// list of options in the menu
$instances = [
'phpc.social',
'mastodon.social',
'mstdn.ca',
];
// display the menu, return the selected text
return $macrame->menu()
->erase() // erase the menu after selection
->interactive($instances, $header);
}
عملکرد اصلی در اینجا فراخوانی است:
$macrame->menu()->interactive(<array of options>, <header>);
ما مجموعه ای از رشته ها را برای نمایش به عنوان گزینه های منو و یک متن هدر اختیاری برای منو ارائه می دهیم menu()->interactive()
و این منو به طور خودکار برای کاربر نمایش داده می شود. انتخاب کاربر به عنوان یک رشته بازگردانده می شود.
همچنین گزینه ای برای پاک کردن منو از صفحه نمایش پس از انتخاب کاربر با اضافه کردن یک تماس به erase()
به زنجیره ما این روش اختیاری است ، اما همه چیز را تمیز نگه می دارد.
پس از عملکرد منو ، می توانیم نحوه دریافت نمونه Mastodon را اصلاح کنیم. ما سعی خواهیم کرد آن را از آرگومان های خط فرمان بخوانیم و اگر هیچ ارزشی نداشته باشد
همانطور که از نام پیدا می کند ، first()
روش مقدار اولین وقوع استدلال ما را برمی گرداند. اگر فیلمنامه خود را اینگونه صدا کردیم:
گذشت ، با ما تماس بگیرید menuInstance()
عملکرد.
$instance = $macrame->args('instance')->first();
if (!$instance) {
$instance = menuInstance($macrame);
}
یک یادداشت جانبی در منوهای یک ظاهر طراحی شده
از خارج از جعبه ، Macrame از سبک و رنگ پیش فرض ترمینال برای منوها استفاده می کند و مورد برجسته را به صورت معکوس تنظیم می کند. اگر بخواهیم با اضافه کردن چند روش اضافی به زنجیره خود ، می توانیم این مسئله را تغییر دهیم. به عنوان مثال ، اگر ترجیح می دهیم مورد برجسته ما به عنوان متن جسورانه و قرمز نشان داده شود ، می توانیم بنویسیم:
$macrame->menu()
->styleSelected('bold')
->colourSelected('red') // colorSelected() also works
->interactive(<array of options>, <header>);
یک مرور کلی در صفحه مستندات منو از کلیه روشهای موجود برای سفارشی کردن رنگ ، سبک و تراز منوها وجود دارد.
در مرحله بعد ، ما قصد داریم نحوه دریافت نام کاربری را برای پذیرش ورودی تعاملی تغییر دهیم. در این حالت ، ما قصد داریم متن ورودی کاربر را با استفاده از آن بخوانیم input()->readline()
بشر این عملکرد است:
function inputUsername(string $instance, Macrame $macrame): string
{
// the prompt for the text input, with bold styling using tags
$prompt = $macrame->text("Username (for $instance): ")
->get();
/* alternate method to apply bold styling:
$prompt = $macrame->text('Username ')
->style('bold')
->get()."(for $instance): ";
*/
// read one line of user input, return the text
return $macrame->input()
->readline($prompt);
}
آخرین خط این عملکرد جایی است که ما کاربر را برای ورودی نظرسنجی می کنیم. در readline()
روش اختیاری را می پذیرد $prompt
استدلال ؛ متنی که به کاربر نشان می دهیم به آنها می گوید چه چیزی را باید وارد کنند. مقدار بازگشت ورودی کاربر به عنوان یک رشته است.
یک یادداشت جانبی در مورد اعتبار ورودی
کاربران اشتباه می کنند. به همین دلیل اعتبارسنجی ورودی مهم است.
Macrame با تعدادی روش از پیش تنظیم شده برای اعتبارسنجی ورودی همراه است. ما می توانیم به همان اندازه که می خواهیم به زنجیره خود اضافه کنیم و در صورت عدم موفقیت هر یک از اعتبار سنج ها ، از کاربر خواسته می شود که دوباره وارد شود. در input()->readline()
عملکرد تا زمانی که تمام اعتبار سنج ها از آن عبور کنند ، یک مقدار را بر نمی گردانند.
بیایید به یک مثال نگاه کنیم:
return $macrame->input()
->isLengthMin(4, 'must be at least 4 characters long')
->doesNotContain('@', 'do not use the @ symbol')
->readline($prompt);
در اینجا ، ما دو آزمون اعتبار سنجی را اعمال می کنیم: متن باید چهار یا چند کاراکتر باشد و نباید حاوی نماد “@” باشد. برای هر دو روش اعتبار سنجی ، آرگومان دوم پیام خطایی است که در صورت عدم موفقیت اعتبارسنجی به کاربر نشان خواهیم داد.
لیست کاملی از توابع اعتبار سنجی از پیش ساخته شده در صفحه مستندات ورودی Macrame موجود است. اگر می خواهیم اعتبار سنجی سفارشی خودمان را بنویسیم ، این نیز پوشانده شده است.
در مورد خروجی “Dots Echo” چیست؟
اگر کاربران ما داده های حساس مانند رمزهای عبور را وارد می کنند ، ما احتمالاً نمی خواهیم کلید های آنها را به ترمینال برگردانیم که در آن صفر های شانه ای می توانند آن را بخوانند.
برای پرداختن به این موضوع ، Macrame نسخه “Dots Echo” را ارائه می دهد readline()
فراخوانی readPassword()
بشر
$macrame->input()->readPassword("enter sensitive data: ");
هر کلید کلید خوانده شده توسط readPassword()
به عنوان یک ستاره تکرار می شود.
در مثال نحوه خواندن یک خط از متن کاربر ، ما یک دسته از کد را برای یک ظاهر طراحی شده در متن سریع دیدیم. بیایید با جزئیات بیشتری به آن نگاه کنیم.
Macrame با استفاده از کدهای ANSI که به ما امکان می دهد هر دو سبک مانند Bold و Italic و رنگ ها را در متن خود استفاده کنیم ، خروجی متن یک ظاهر طراحی شده را به ترمینال امکان پذیر می کند.
ما می توانیم این کار را در فیلمنامه خود یکی از دو روش انجام دهیم. روش هایی مانند style()
وت colour()
(یا color()
) ، یا می توانیم از یک سیستم برچسب گذاری اساسی با متن استفاده کنیم.
بیایید ابتدا به روش روش نگاه کنیم.
$prompt = $macrame->text('Username ')
->style('bold')
->colour('blue')
->get()."(for $instance): ";
در اینجا ، ما یک شیء “متن” را با استفاده از macrame ایجاد کردیم text()
روش ، سپس قبل از بازگشت آن به عنوان رشته با استفاده از یک سبک و رنگ استفاده کنید get()
بشر
توجه داشته باشید که روش های سبک و رنگ برای تمام متن موجود در رشته اعمال می شود. اگر بخواهیم متن سبک و رنگی را با متن ساده مخلوط کنیم ، باید تعدادی بستر ایجاد کنیم و آنها را با هم جمع کنیم. این می تواند دست و پا گیر باشد ، به خصوص اگر با متن زیادی سروکار داشته باشیم.
از طرف دیگر ، ما می توانیم از سیستم برچسب زدن Macrame استفاده کنیم تا متن خود را کمی ساده تر کنیم. در اینجا یک مثال آورده شده است:
$prompt = $macrame->text("Username (for $instance): ")
->get();
متن بین and
tags will, unsurprisingly, be bolded. there is a full list of all the tags in the documentation.
an important thing to note is that the tag closes all of the preceding tags. this is due to the behaviour of ANSI escape codes.
this means that nesting tags does not work the way we might expect. for instance, in this example, the first tag closes both the
and
tags:
"this is red this is red and bold this is plain";
فیلمنامه مثال ما تاکنون به نظر می رسد:
#!/usr/bin/env php
require __DIR__ . '/vendor/autoload.php';
use Gbhorwood\Macrame\Macrame;
// Instantiate a Macrame object.
// The argument is the name of the script as seen by ps(1)
$macrame = new Macrame("Example Macrame script");
// Enforce that the script only runs if executed on the command line
if ($macrame->running()) {
// Validate that the host system can run Macrame scripts. Exit on failure
$macrame->preflight();
/**
* Handle the -v or --version arguments
*/
if ($macrame->args('v')->exists() || $macrame->args('version')->exists()) {
$macrame->text('1.0')->write();
$macrame->exit();
}
/**
* Handle the --instance= argument if present, or poll user for instance
* with dynamic menu if not.
*/
$instance = $macrame->args('instance')->first();
if (!$instance) {
$instance = menuInstance($macrame);
}
/**
* Handle the --username= argument if present, or poll user for username
* with text input if not
*/
$username = $macrame->args('username')->first();
if (!$username) {
$username = inputUsername($instance, $macrame);
}
// exit cleanly
$macrame->exit();
}
/**
* Display a dynamic menu of instances to the user, return
* the selected text.
*
* @param Macrame $macrame
* @return string
*/
function menuInstance(Macrame $macrame): string
{
$header = "Select your instance";
// list of options in the menu
$instances = [
'phpc.social',
'mastodon.social',
'mstdn.ca',
];
// display the menu, return the selected text
return $macrame->menu()
->erase() // erase the menu after selection
->interactive($instances, $header);
}
/**
* Display a text input to the user, return the input text.
*
* @param string $instance
* @param Macrame $macrame
* @return string
*/
function inputUsername(string $instance, Macrame $macrame): string
{
// the prompt for the text input, with bold styling using tags
$prompt = $macrame->text("Username (for $instance): ")
->get();
/* alternate method to apply bold styling:
$prompt = $macrame->text('Username ')
->style('bold')
->get()."(for $instance): ";
*/
// read one line of user input, return the text
return $macrame->input()
->doesNotContain('@', 'do not use the @ symbol')
->readline($prompt);
}
تاکنون ، ما آرگومان های خط فرمان خواندن ، دریافت ورودی کاربر از منوها و متن را پوشش داده ایم و برخی از یک ظاهر طراحی متن اصلی را برای خروجی انجام داده ایم. در پست بعدی ، ما ادامه خواهیم داد:
- اجرای یک تابع در پس زمینه در حالی که ما یک چرخش انیمیشن را به کاربران نشان می دهیم
- نوشتن با خیال راحت به پرونده ها
- داده های آرایه به عنوان یک جدول ASCII با فرمت زیبا
- صفحه بندی طولانی مدت
- خروجی سطح اعلامیه اساسی
🔎 این پست در ابتدا در وبلاگ فنی Grant Horwood ظاهر شد