برنامه نویسی

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

PHP به عنوان یک زبان اسکریپت خط فرمان مورد توجه زیادی قرار نمی گیرد. این شرم آور است ، زیرا PHP دارای ویژگی های زیادی است که آن را برای نوشتن برنامه های ترمینال انتخاب خوبی می کند.

در این سری ، ما با استفاده از کتابخانه Macrame ، نوشتن اسکریپت های خط فرمان تعاملی را خواهیم نوشت. ما از طریق ساختن یک پروژه مثال ، اسکریپتی که لیستی از پیروان کاربر Mastodon را از ابتدا تا انتها بدست می آورد ، کار خواهیم کرد و موضوعاتی از قبیل دریافت و اعتبارسنجی ورودی کاربر ، ساختن منوهای تعاملی ، دسترسی به آرگومان های خط فرمان ، دسترسی را پوشش می دهیم. پرونده ها با خیال راحت ، متن خروجی یک ظاهر طراحی شده و اجرای توابع در پس زمینه در حالی که به کاربران ما یک اسپینر متحرک نشان می دهد.

اطلاعات بیشتر در مورد Macrame را می توان در سایت اسناد یافت.

پروژه نمونه

پروژه ای که ما از طریق آن کار خواهیم کرد ، یک اسکریپت خط فرمان ساده است که لیستی از پیروان کاربر Mastodon را برمی گرداند. دویدن به نظر می رسد این:

GIF متحرک پروژه نمونه در حال اجرا
نمونه اسکریپت در عمل

کاربر نمونه 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 ظاهر شد

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا