رفع خطای محدودیت حافظه (memory_limit) در کومپوزر

امروز اومدم یه پکیج به لارول اضافه کنم و با خطای زیر روبرو شدم:

PHP Fatal error:  Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.

تو نگاه اول به نظر میرسه این خطا مربوط به memory_limit در php هست ولی گویا به تنهایی php نیست و لازمه composer هم مقدار دهی بشه. اول از همه بریم سرغ php

برای اینکه ببینیم memory_limit در php چی ست شده از دستور زیر استفاده کنین (اگر مقدار برابر -۱ بود یعنی محدودیتی براش نذاشتین):

php -r "echo ini_get('memory_limit').PHP_EOL;"

حالا برای اینکه memory_limit  رو در php.ini تغییر بدیم، بسته به اینکه با چه برنامه ای و در چه سیستم عاملی php رو نصب کردین محل نصب php.ini متفاوته. یه راه حل ساده میتونه این باشه در داخل ترمینال دستور زیر رو تایپ کنین:

For linux
php -i | grep php.ini

For windows:
php -i | findstr php.ini

خب این گزینه بهتون میگه php.ini که مربوط به php اجرا شده هست کجا قرار داره (ممکنه رو سیستمتون چند تا php داشته باشن) این دستور php که بصورت global نصب شده رو جارا میکنه.

پیدا کردن فایل php.iniهمونطور که میبنین مسیر فایل php.ini من اینه: /opt/lampp/etc/php.ini  با دستور زیر این فایل رو ویرایش کنین و دنبال memory_limit بگردین:

sudo nano /opt/lampp/etc/php.ini

برای اینکه داخل این فایل جستجو کنین از میانبر Ctrl + W استفاده کنین و بعد عبارت memory_limit رو تایپ کنین. حالا مقدارش رو به ۱.۵جی عوض کنین. مقدار رم پیشنهادی برای php و کومپوزر حداقل ۱.۵گیگ هست. البته نیازی نیست و شما با ۱۲۸ هم کارتون راه میافته ولی حداقل ۵۱۲ بذارین دیگه! در آخر برای خروچ Ctrl + X بزنین ذخیره کنین و خارج بشین.

حالا میمونه مقدار COMPOSER_MEMORY_LIMIT که یک متغیر محیطی هست و در فایل composer.phar هم میتونین پیداش کنین. در داخل لینوکس / اوبونتو دستور زیر رو تایپ کنین تا مقدار فعلی رو ببینین:

printenv COMPOSER_MEMORY_LIMIT

اگر مقداری نمایش داده نشد، به این خاطره که تا بحال این متغیر ست نشده. حالا ۱نکته: جستجویی که من انجام دادم متوجه شدم محدودیتی وجود داره که اگر این متغیر ست بشه مقدارش رو از memory_limit در php میگیره و در جای دیگه راه حل هایی که ارائه شده بود مقدارش رو وارد میکردن (اینجا و اینجا و اینجا رو ببینین).

با دستور which composer  پیدا کنین کومپوزر کجا نصب شده یا فعاله. برای من بجای composer.phar آدرس /usr/bin/composer  وجود داشت. حالا دستور زیر رو بزین تا آپدیت بشه

php -d memory_limit=1.5G /usr/bin/composer update

راه حل های دیگه ای هم مثل ست کردن متغیر COMPOSER_MEMORY_LIMIT ولی من از این روش نتیجه ثابتی نگرفتم.

در آخر هم یه نکته رو دوباره بگم که برای COMPOSER_MEMORY_LIMIT و memory_limit اگر مقدار رو برابر -۱ بذارین دیگه لازم نیست هرزگاهی سر بزنین و منابع رو افزایش بدین و بصورت unlimited در نظر میگیره.

بروز رسانی: روش بالا بعد رستارت کردن از بین میره ظاهرا! فعلا از این روش سریع و موقتی برای حل مسئله استفده میکنم. داخل ترمینالتون کد زیر رو ببزنین. (البته میشه این متغیر رو بصورت ثابت و محیطی هم تعریف کرد)

export COMPOSER_MEMORY_LIMIT=-1

 

راهنمای سریع استفاده از ربات تلگرام در لاراول Laravel Telegram Bot

در این مقاله خیلی سریع وخلاصه میریم سراغ ایجاد ربات و اتصال اون به لاراول.
توسط کد زیر پکیج کار با تلگرام رو به لاراول اضافه کنین:

composer require irazasyed/telegram-bot-sdk

حالا به آرایه providers که در مسیر config/app.php هست اضافه میکنیم.

Telegram\Bot\Laravel\TelegramServiceProvider::class,

حالا به آرایه aliases کد زیر رو اضافه میکنیم تا Telegram به فاساد هامون اضافه بشه.

 'Telegram' => Telegram\Bot\Laravel\Facades\Telegram::class,

حالا که سرویس و فاساد اون رو اضافه کردیم فایل کانفیگ تلگرام رو با دستور زیر انتشار میدیم (میاریم به فولدر config)

php artisan vendor:publish --provider="Telegram\Bot\Laravel\TelegramServiceProvider"

حالا میریم به تلگرام و ربات پدرخانده @BotFather رو استارت میزنیم با دستور /newbot یک ربات جدید ایجاد میکنیم. اول اسم ربات و دوم نام کاربری اون رو وارد میکنیم در آخر هم وقتی ربات به درستی ایجاد شد، تلگرام کد token HTTP API میده که بهش تو فایل .env نیاز داریم و به صورت زیر در این فایل وارد میکنیم:

TELEGRAM_BOT_TOKEN=525012101:AAEwy9R1SCpq0V_Bpkgqm9Z4nbrWZaNt_Kg

خب حالا نیاز به یک کانال تلگرام داریم که رباتمون رو داخلش ادد کنیم.

به فایل config/telegram.php میریم و در قسمت ربات های نام رباتمون رو مینویسیم (قسمت username). کد زیر

'bots' => [
    'mybot' => [
        'username' => 'tutsforwebbot',
        'token' => env('TELEGRAM_BOT_TOKEN', ''),
        'certificate_path' => env('TELEGRAM_CERTIFICATE_PATH', ''),
        'webhook_url' => env('TELEGRAM_WEBHOOK_URL', ''),
        'commands' => [
        ],
    ],
],

برای بروز رسانی کشمون هم از دستور زیر استفاده میکنیم:

php artisan config:cache

در تلگرام هر چت (کانال، چت، گروه پی وی یا…) یه اتاق گفتگو حساب میشه و برای ارسال پیام توسط رباط ما نیاز به شماره اون اتاق داریم که البته اسمش chat_id هست. برای اینکه شماره اتاق گفتگو رو پیدا کنیم و کار با رباط تلگرام یه کنترلر برای رباط تلگرام ایجاد میکنیم:

php artisan make:controller TelegramBotController

و کد های زیر رو به کنترلرمون اضافه میکنیم

<?php
 
namespace App\Http\Controllers;
 
use Telegram\Bot\Laravel\Facades\Telegram;
 
class TelegramBotController extends Controller
{
    public function updatedActivity()
    {
        $activity = Telegram::getUpdates();
        dd($activity);
    }
}

کد بالا پیام های اتاق گفتگو رو بصورت لاگ نمایش میده و همچنین شماره اون رو. با مسیر زیر کنترلرمون رو فعال میکنیم:

Route::get('/updated-activity', 'TelegramBotController@updatedActivity');

حالا به مرورگر میریم و آدرس /updated-activity رو تایپ میکنیم، اگر کانال ما خالی باشه مقدار [] برمیگرده ولی وقتی یک پیام ایجاد کنیم (خودمون یک پیام در کانال منتشر کنیم) و دوباره تست میگیریم. خروجی شبیه این میشه:

array:1 [▼
  ۰ => Update {#348 ▼
    #items: array:2 [▼
      "update_id" => 21432106
      "channel_post" => array:4 [▼
        "message_id" => 12
        "chat" => array:4 [▼
          "id" => -1001361379586
          "title" => "Hamidreza bot test"
          "username" => "hamidrezabot_test"
          "type" => "channel"
        ]
        "date" => 1568741639
        "text" => "SalamDonya"
      ]
    ]
  }
]

اگر قبلا پیامی در گروه فرستاده بودین آخرین ایندکس رو چک کنین. در این آرایه در قسمت ایندکس chat قسمت id یک شماره نوشته شده -۱۰۰۱۳۶۱۳۷۹۵۸۶ این شماره رو کپی میکنیم و در فایل .env متغیر زیر رو اضافه میکنیم

TELEGRAM_CHANNEL_ID=-1001361379586

و سپس کش رو دوباره ریفرش میکنیم

php artisan config:cache

حالا به کنترلر TelegramBotController متد زیر رو اضافه میکنیم

public function sendMessage()
    {
        Telegram::sendMessage([
            'chat_id' => -1001361379586,//env('TELEGRAM_CHANNEL_ID', ''),
            'parse_mode' => 'HTML',
            'text' => 'اولین پیام تست ربات تلگرام'
        ]);
    }

البته من مستقیم شماره chat_id رو وارد کردم ولی شما میتنین از متغیر محیطی .env استفاده کنین که کدشو کامنت کردم.
آدرس sendMessage رو در روت خودمون وارد میکنیم و بعد در مرورگر تست میکنیم.

Route::get('/sendMessage', 'TelegramBotController@sendMessage');

 

منبع: https://tutsforweb.com/sending-notifications-to-telegram-messenger-with-laravel

خیلی ساده SOAP چیست و چطور در php نصب و فعال کنیم

SOAP مخفف کلمات Simple Object Access Protocol هست و همونطور که از ترجمش مشخصه (پروتکل ساده دسترسی به شی – ترجمش خیلی عجیب شد!) یک پروتکل ساده برای ارتباط (پیام رسان) بین اشیا یا بهتر بگم بین برنامه ها هست که مبتنی بر XML طراحی شده و از بستر پروتکل های مختلف مثل HTTP و SMTP و… پیام ها رو منتقل میکنه.

تو یه جمله یه چی شبیه جیسان JSON هست ولی مبتنی بر XML برای ردوبدل کردن اطلاعات بین برنامه ها در بستر های مختلف که از پروتکل های مختلف هم پشتیبانی میکنه (HTTP SMTP و …).

مزیتش اینه سادس و فایروال بلاکش نمیکنه! عیبشم اینه که امنیت کمی داره

برای فعال کردنش در php داخل ویندوز به فایل php.ini روجوع کنید و سیمیکالون جلوی extension=php_soap.dll رو بردارین و آپاچی رو رستارت کنین. حلله!
در اوبونتو و کلا سیستم های لینوکس اگه زمپ (لمپ xampp lampp) نصب کرده باشید بخودیه خود فعاله ولی برای اینکه مطمئن بشین دستور php -m | grep soap رو تایپ کنین. اگر نبود یا php  بصورت مجزا نصب کردید برای php7 دستور زیر رو تایپ کنین

PHP-7
sudo apt install php7.0-soap
sudo systemctl restart apache2

PHP-5
apt-get install php-soap
sudo systemctl restart apache2

 

 

روش بالا برای وقتی که سرور رو خودتون کانفیگ کرده باشید جواب میده، من برای اوبنتوی خودم از زمپ استفاده کردم؛ برای نصب soap بر روی سیستم عامل ubutntu که وب سرویش رو با xampp را انداختید از روش زیر استفاده کنید:

cd /opt/lampp/bin
sudo ./pear install soap
In PHP code, require_once("SOAP/Client.php");

تکته اینکه من از require_once(“SOAP/Client.php”) استفاده نکردم و فقط تو کد لاراول خودم (اگه از namespace استفاده میکنید)  خط زیر رو نوشتم

$client = new \SoapClient($this->url);

منبع جواب Pear SOAP and XAMPP on Ubuntu

خطای bash: php: command not found

بعد نصب زمپ و احتمالا نصب کومپوزر هنگامی که دستور php رو در کمند لاین تایپ میکنین حتما با خطای bash: php: command not found روبرو میشین. دلیلش هم اینه php  در زیر شاخه زمپ نصب شده و برای استفاده global باید اونو در فولدر باینری سیستم لینک کنین. چطوری؟ لمپ بصورت پیشفرض در آدرس زیر نصب میشه

/opt/lampp

 

و تمامی متعلقاتشم در همین پوشه هست. کافیه دستور زیر رو تایپ کنیم تا لینک میانبر ایجاد بشه

sudo ln -s /opt/lampp/bin/php /usr/bin/php

 

موردی که بعد این بهتر بهش توجه داشته باشین اینه که احتمالا بخاط تست و خطا یا… فایل باینری php  در مسیر های دیگه ای هم نصب شده. برای اینکه ببینیم php که توسط xampp نصب شده در کدوم مسیره به آدرس http://localhost/dashboard/phpinfo.php برین و «Loaded Configuration File » مسیر فایل php.ini رو نشون میده که تو سیستم من /opt/lampp/etc/php.ini هست و  فایل باینریه php در مسی /opt/lampp/bin/php هست (چون متن rtl بود / جلوی php اوند)

همین موضوع که از یک فایل باینتری دیگه ایتفاده کرده بودم باعث شد هنگام اجرای دستور php artisan  با خطای «PHP Warning: PHP Startup: Unable to load dynamic library » مواجه بشم که به اشتباه رفتم فایل php.ini همون باینتری رو ویرایش کردم و سیمیکالون جلوی extension=php_mbstring.dll رو برداشتم و این اشتباه دوم بود چرا که فایل های dll مختص ویندوز هست و نه لینوکس. در لینوکس شما باید متعلقات php  رو بصورت sudo apt-get install php-mbstring نصب کنین و برای غیر فعال کردنش از دستور sudo phpdismod mbstring و فعال کردن دوباره دستور sudo phpenmod mbstring استفاده کنین.

بروز رسانی: امان از این حافظه! فراموش کردم قبلا این کارو انجام داده بودم و از اونجایی که دوباره اوبونتو نصبیدم مجبور شدم دوباره این کارو انجام بدم و یادم نبود… دنبال راه حل گشتم و راه دیگه ای پیدا کردم. راه حل دوم:

cd ~
nano .profile

//متن زیر رو به انتهای فایل اضافه کنین
PATH="/opt/lampp/bin:$PATH"

 

بروز رسانی: روش اول global هست و راحتتر در همه یوزر ها خصوصا  root میتونید باهاش کار کنید.

پیروز باشید 🙂