اذهب إلى المحتوى

Sam Ahw

الأعضاء
  • المساهمات

    1388
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    16

إجابات الأسئلة

  1. إجابة Sam Ahw سؤال في نوع بيانات String كانت الإجابة المقبولة   
    غير واضح في السؤال ماهي لغة البرمجة التي يتم استعمالها، فيختلف تعريف المتغيّرات من لغة لأخرى، ففي بعض اللغات يجب ذكر نوع البيانات التي سيتم تخزينها في المتغيّر مثال لغة الجافا:
    String name = "myName"; وفي لغات أخرى يتم فقط وضع القيمة بشكل مباشر ضمن المتغيّر دون الحاجة لذكر نوع البيانات، مثال في الجافاسكريبت:
    var name = "myName"; --> (string) وأيضاً في بايثون:
    name = "Hello" عموماً، طريقة تعريف المتغيّر المذكورة في السؤال ليست خاطئة، ولكن قد تختلف من لغة برمجة لأخرى.
  2. إجابة Sam Ahw سؤال في تنسيقات CSS لا تظهر في لارافيل كانت الإجابة المقبولة   
    في لارافيل عند التعامل مع الملفات الثابتة static مثل الصور و ملفات التنسيقات CSS وملفات الجافاسكريبت يجب الإشارة لها دوماً عن طريق asset لتجنب ظهور أي مشاكل عند تغيير المسار أو اسم النطاق في المشروع أو عند نشره واستخدام اتصال آمن https، لذلك ربط الملفات ضمن صفحات blade يجب أن يكون كالتالي:
    لملفات التنسيقات CSS:
    <link href="{{ asset('css/main.css') }}" rel="stylesheet" type="text/css" > أو <link href="{{ URL::asset('css/main.css') }}" rel="stylesheet" type="text/css" > لملفات الجافاسكريبت:
    <script type="text/javascript" src="{{ asset('js/custom.js') }}"></script> أو <script type="text/javascript" src="{{ URL::asset('js/custom.js') }}"></script> وللصور:
    {{ asset('img/photo.jpg'); }} وفي بعض الأحيان قد تظهر لك هذه المشكلة ليس بسبب سوء عملية الربط وإنما بسبب صلاحيات الوصول على المجلّدات الحاوية على هذه الملفات في ويندوز أو نظام التشغيل الذي تقوم باستخدامه، لذلك يمكنك تجربة تشغيل المشروع في لارافيل عن طريق استخدام الأمر التالي:
    php -S localhost:9000 -t public  
  3. إجابة Sam Ahw سؤال في كيف أشارك البيانات بين Views في لارافيل كانت الإجابة المقبولة   
    يوجد عدّة طرق لمشاركة البيانات بين views في لارافيل:
    فيمكنك تنفيذ ذلك عن طريق استخدام متحكم رئيسي تضع فيه جميع البيانات أو العمليات العامة global التي ترغب بمشاركتها، ثم تستطيع الوصول إليها عن طريق باقي المتحكمات بالوراثة، كالتالي:
    class BaseController extends Controller { public function __construct() { /نضع البيانات التي نرغب بمشاركتها $user = User::all(); // نقوم باستخدام share View::share('user', $user); } } الطريقة الثانية هي باستخدام الفلاتر Filter، فيقوم لارافيل بتنفيذ الفلتر قبل الطلب request عن طريق App:before:
    App::before(function($request) { View::share('user', User::all()); }); أو يمكنك كتابة الفلتر الخاص بك أيضاً:
    Route::filter('user-filter', function() { View::share('user', User::all()); }); الطريقة الثالثة هي باستخدام وسيط middleware ووضعه في جميع المسارات التي ستتشارك البيانات كالتالي:
    Route::group(['middleware' => 'SomeMiddleware'], function(){ // نضع هنا المسارات ضمن مجموعة واحدة تتشارك البيانات }); class SomeMiddleware { public function handle($request) { \View::share('user', auth()->user()); } } وأخيراً، يمكنك أيضاً استخدام viewComposer في لارافيل، فنقوم بإنشاء مجلّد خاص ضمن المسار App\Http\ViewComposers، ونضيف على serviceProvider:
    namespace App\Providers; use Illuminate\Support\ServiceProvider; class ViewComposerServiceProvider extends ServiceProvider { public function boot() { view()->composer("ViewName","App\Http\ViewComposers\TestViewComposer"); } } ثم نقوم بإضافة الصف TestViewComposer ضمن config/app.php:
    namespace App\Http\ViewComposers; use Illuminate\Contracts\View\View; class TestViewComposer { public function compose(View $view) { $view->with('ViewComposerTestVariable', "Calling with View Composer Provider"); } } وعندها يمكننا استدعاء البيانات بأي view كالتالي:
    {{$ViewComposerTestVariable}}  
  4. إجابة Sam Ahw سؤال في الوصول إلى الصور المخزنة ضمن المجلد storage في لارافيل كانت الإجابة المقبولة   
    وفقاً للتوثيق الرسمي في لارافيل، يفضّل وضع الملفات العامة مثل الصور ضمن المجلّد public، ولكن في حال وجود الملفات في مجلّد آخر ولإتاحته على الويب يمكن إنشاء رابط يدعى symbolic من المسار public/storage إلى المسار storage/app/public كالتالي:
    ln -s /path/to/laravel/storage/app/public /path/to/laravel/public/storage الآن يمكنك إضافة رابط URL ضمن ال views باستخدام asset helper بالشكل التالي:
    echo asset('storage/file.txt'); ولكن في بعض الحالات لدى بعض الاستضافات المشتركة لا يمكنك إنشاء symbolic link عندها يمكنك إنشاء مسار جديد route في لارافيل والتوجيه إليه عند طلب الملفات. مثال:
    Route::get('storage/{filename}', function ($filename) { $path = storage_path('public/' . $filename); if (!File::exists($path)) { abort(404); } $file = File::get($path); $type = File::mimeType($path); $response = Response::make($file, 200); $response->header("Content-Type", $type); return $response; }); أما للصور، فيمكن عن طريق لارافيل استخدام مكتبة الصور كالتالي:
    Route::get('storage/{filename}', function ($filename) { return Image::make(storage_path('public/' . $filename))->response(); }); الآن يمكن ببساطة وضع الرابط التالي في أي صفحة view :
    http://somedomain.com/storage/image.jpg مع استبدال somedomain باسم النطاق الخاص بك.
  5. إجابة Sam Ahw سؤال في ظهور خطأ mcrypt في لارافيل كانت الإجابة المقبولة   
    إن الإضافات المفعّلة للويب والإضافات الموجودة التابعة لموجّه الأوامر قد تختلف في نظام التشغيل. لذلك وللتأكد من تفعيل هذه الإضافة قم بتنفيذ الأمر التالي في موجه الأوامر:
    php -m أيضاً، في نظام تشغيل ubuntu مثلاً، عند تنفيذ أمر التحميل التالي:
    sudo apt-get install php5-mcrypt فلا يتم تحميل الإضافة ضمن mods-available، فتحتاج بعدها إلى إجراء الأمر التالي لنقلها:
    sudo ln -s /etc/php5/conf.d/mcrypt.ini /etc/php5/mods-available/mcrypt.ini ثم تحتاج إلى تفعيل mod وإعادة التشغيل في حال كان خادم الويب apache كالتالي:
    sudo php5enmod mcrypt sudo service apache2 restart وبدءً من الإصدار الخامس في لارافيل لم تعتد تعتمد على الإضافة mcrypt وأيضاً في النسخ الحديثة من php لم تعد موجودة.
  6. إجابة Sam Ahw سؤال في الوقت المستغرق للموافقة على تطبيقي كانت الإجابة المقبولة   
    المذكور في غوغل أنه الوقت الطبيعي لمراجعة التطبيقات هو حوالي 3 أيام من تاريخ التقديم، ولكن قد يستغرق في بعض الأحيان وقت أطول قليلاً.
    لا يمكنك تسريع العملية، ولكن في حال وجود أي مشكلة سيقومون بإرسال بريد الكتروني لك يحوي التفاصيل، لذلك قم بمراجعة بريدك الالكتروني باستمرار.
  7. إجابة Sam Ahw سؤال في تعريب كاربون و الترتيب من الاحدث ( لارافيل ) كانت الإجابة المقبولة   
    إن كاربون يدعم العديد من اللغات ومنها العربية دون الحاجة لاستخدام مكتبات إضافية، يمكنك في أول الصفحة بين سطور التضمين ومباشرة بعد تضمين كاربون اختيار اللغة على الشكل التالي:
    use Carbon\Carbon; Carbon::setLocale('ar');  
    يوجد العديد من الطرق وكلها تؤدي إلى نفس النتيجة لذلك يمكنك استخدام النمط الذي تفضلّ، مثال:
    $newss = News::orderBy('created_at', 'desc')->take(10)->get(); أما في حال كان قصدك في post:All الحصول مثلاُ على آخر مقالات ضمن تصنيف أو مجموعة محددة، يمكنك كتابة التالي:
    //الحصول على المجموعات $categories = Category::all(); //وضع النتيجة النهائية $latest_posts_by_category = []; $ids = []; foreach($categories as $category){ $post = Post::with(['categories' => function($query){ $query->latest()->first(); }]) ->latest() ->whereHas('categories', function($query) use($category) { $query->whereName($category->name); })->take(1)->first(); if(!in_array($post->id, $ids)){ $latest_posts_by_category[] = $post; $ids[] = $post->id; } }
  8. إجابة Sam Ahw سؤال في مشكلة CORS بين لارافيل و Angular كانت الإجابة المقبولة   
    إن السبب في ذلك هو أن middlewares في لارافيل والموجودة ضمن مصفوفة $routeMiddleware يتم تطبيقها والتحقق منها مباشرةً بعد تأكد لارافيل من المسار المزود عن طريق HTTP والسبب في ذلك لأن مسارات الطلبات المختلفة قد يكون لها middlewares مختلفة أيضاً.
    لأنه عندما يتم إرسال الطلبات POST, PUT, DELETE وغيرها... سيتم إرسالها إلى /api/authenticate والمتصفح يقوم بإرسال Options أولاً وبالتالي لارافيل يقوم بتسجيل المسار والتحقق من تطابقه مع المسارات الموجودة قبل الدخول والتحقق في middlewares  وبما أن الموارد resources لا تحوي Options أو دوال معينة للتعامل معها لن تقوم بالتالي بالتحقق من أي middleware مرفق مع المسار وهنا يحدث الخطأ. مثال:
    Route::group(['middleware' => 'cors'], function () { Route::group(['prefix' => 'api'], function() { Route::resources('authenticate', 'AuthenticateController', ['only' => ['index']]); Route::post('authenticate', 'AuthenticateController@authenticate'); }); }); أما middlewares الموجودة ضمن مصفوفة $middleware يتم التحقق منها وتطبيقها (قبل) أن يقوم لارافيل بتسجيل المسار والتحقق من وجوده.
    فعملية المطابقة matching تستدعي findRoute الموجود ضمن:
    vendor/laravel/framework/src/Illuminate/Routing/Router.php على الشكل التالي:
    /** * Find the route matching a given request. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Routing\Route */ protected function findRoute($request) { $this->current = $route = $this->routes->match($request); $this->container->instance(Route::class, $route); return $route; } لذلك لحل هذه المشكلة، يجب استخدام middleware عام أي (global) والذي بدوره يستقبل الخيارات الموجودة ضمن الترويسة OPTIONS ولاختصار الوقت والجهد يمكن استعمال مكتبة fruitcake / laravel-cors الموجودة والتي يمكن إضافتها إلى لارافيل والتي ستقوم بدورها باستعمال CORS الخاصة بها مثل أن يكون cors خاصة لكل مسار أو مجموعة أو لاحقة prefix في ملف api.php وتقوم بحل المشكلة الموجودة.
  9. إجابة Sam Ahw سؤال في مشكلة Throttle Access في API لارافيل كانت الإجابة المقبولة   
    يجب أن تقوم بتمرير رقم IP Address للزبون مع ترويسة X_FORWARDED_FOR وبهذه الطريقة لن يتم حجب رقم IP Address للسيرفر الثاني.
    ويمكن القيام بذلك كالتالي:
    Route::get('/', function (Request $request) { $client = new \GuzzleHttp\Client(); $request = $client->request('GET', '/api/example', [ 'headers' => ['X_FORWARDED_FOR' => $request->ip()] ]); $response = $request->getBody(); }); حيث يتم وضع رقم IP ضمن الترويسة 'X_FORWARDED_FOR.
    ثم في السيرفر الأساسي يجب أن تقوم بإضافة عنوان السيرفر الآخر ضمن trusted proxy ضمن المسار التالي:
    App\Http\Middleware\TrustProxies ليتم أخذ عنوان IP Address من الترويسة Header بالشكل المطلوب. ويمكن القيام بذلك كالتالي:
    class TrustProxies extends Middleware { /** * The trusted proxies for this application. * * @var array */ protected $proxies = [ '192.168.1.1', // <-- يتم هنا وضع عنوان السيرفر الثاني ]; //... } الآن مع كل عملية استدعاء من الشكل على السيرفر الأول، ستتمكن من الوصول إلى عنوان الزبون Client IP بدلاً من عنوان السيرفر الثاني وبالتالي سيتم التخلص من الاختناق الحاصل:
    $request->ip()  
  10. إجابة Sam Ahw سؤال في كيفية تخصيص رسالة الخطأ ThrottleRequest في لارافيل كانت الإجابة المقبولة   
    إن لارافيل بشكل افتراضي لديه آلية لالتقاط الأخطاء وبالتالي لديه مجموعة واسعة من رسائل الخطأ الموجودة بشكل تلقائي ضمن المكتبات المستخدمة، و رسالة TOO MANY REQUESTS من ضمن هذه الرسائل.
    يمكنك إنشاء extend للوسيط middleware الذي تقوم باستخدامه وعمل override لـ buildException لإنشاء رسالة خطأ خاصة جديدة بدلاً من الرسالة الافتراضية في لارافيل عندما يقوم هذا الصف برمي خطأ من نوع ThrottleRequestsException
    أو يمكنك إنشاء handler جديد خاص بك للتحكم بالأخطاء المراد إنشاء رسائل جديدة لها وبالتالي يمكنه التقاط الأخطاء من نوع ThrottleRequestsException ومعالجتها بالشكل المطلوب.
    مثال، ضمن Exceptions/Handler.php يمكننا كتابة التالي:
    use Illuminate\Http\Exceptions\ThrottleRequestsException; public function render($request, Exception $exception) { if ($exception instanceof ThrottleRequestsException) { //--> هنا يمكننا تنفيذ الذي نرغب به مثل إرسال رسالة خاصة أو تنفيذ إجرائية معينة } return parent::render($request, $exception); }  
  11. إجابة Sam Ahw سؤال في تمرير الصور من بايثون إلى لارافيل كانت الإجابة المقبولة   
    يجب ترميز الملف (الصورة) بالصيغة base64 وطباعته في shell قبل نقله إلى لارافيل، ثم يتم فك الترميز base64 في لارافيل.
    فبفرض لديك السكريبت التالي في بايثون:
    import base64 from io import BytesIO from PIL import Image, ImageDraw background = Image.new('RGBA', (500, 500)) d = ImageDraw.Draw(background) d.text((10, 10), "Hello World", fill=(255, 255, 0)) imgByteArr = BytesIO() background.save(imgByteArr, format='PNG') imgByteArr = base64.b64encode(imgByteArr.getvalue()) --> يتم هنا الترميز في base64 قبل الطباعة print(imgByteArr) ثم في لارافيل يتم استدعاء process وانتظار انتهاء تنفيذ السكريبت واختبار حدوث أي خطأ أثناء التنفيذ عن طريق استخدام  process->isSuccessful كالتالي:
    public function newImage() { $process = new Process('python3 /path-to-script/shell.py'); $process->run(); if ( ! $process->isSuccessful()) { return abort(404); } return response(base64_decode(str_replace_first('b', '', $process->getOutput())))->header('Content-Type', 'image/png'); } حيث يتم استخدام base64_decode لفك الترميز ونمرر له القيمة الناتجة من تنفيذ السكريبت السابق عن طريق  process->getOutput وأخيراً يجب إضافة الترويسة المناسبة لنمط الملف، في حال (صورة) يكون image/png.
  12. إجابة Sam Ahw سؤال في ظهور خطأ cURL error 60 في لارافيل كانت الإجابة المقبولة   
    إن سبب ظهور المشكلة فقط عند تنفيذ command هو لأن CLI في لارافيل يستخدم php.ini مغاير للذي يتم استخدامه ضمن المشروع أو بيئة التطوير. ويمكن حل المشكلة إما عن طريق التعديل على ملف GuzzleHttp\Client بتغيير مفتاح verify إلى القيمة false بدلاً من true من configureDefaults بالشكل التالي:
    $this->client = new GuzzleClient(['defaults' => [ 'verify' => false ]]); ويمكن أيضاً تحميل الشهادة الرقمية باللاحقة .pem ثم تعديل ملف php.ini الخاص بالبيئة التي يتم استخدامها كالتالي:
    curl.cainfo = "[pathtothisfile]\cacert.pem" حيث نستبدل pathtothisfile بالمسار المطلق للشهادة ليتم التعرف عليها بداخل الملف php.ini
    ومن ثم نقوم بالإشارة للشهادة بالشكل التالي:
    $guzzle->setDefaultOption('verify', '/path/to/cacert.pem'); ففي كلتا الحالتين يجب أن يكون التحقق ضمن GuzzleHttp\Client في لارافيل على الشكل التالي:
    // تعطيل التحقق $guzzle->setDefaultOption('verify', false); // استخدام الشهادة $guzzle->setDefaultOption('verify', '/path/to/cacert.pem');
  13. إجابة Sam Ahw سؤال في مشكلة توجيه دومين فرعي في لارافيل كانت الإجابة المقبولة   
    إن مسارات التوجيه في لارافيل تستخدم آلية first-come-first-serve أي تتلقى المسارات المختلفة بالترتيب ضمن الملف بدءً من المسار الأول. لذلك في حال كانت إضافة الدومين (اسم النطاق) بعد المسار الأساسي لن يتم تمييزه في لارافيل وسيتم التوجيه إلى المسار الأساسي الأول (النطاق الأساسي).
    مثال:
    Route::group(['domain' => 'admin.localhost'], function () { Route::get('/', function () { return "هذه المجموعة ستتلقى الطلبات عبر 'admin.localhost/'"; }); }); Route::get('/', function () { return "ثم المجموعة الأساسية لتلقي المسارات الأساسية للنطاق الأساسي"; }); أما في حال تمت كتابة المسارات بالترتيب التالي فلن يتم تمييز مسارات النطاق الفرعي:
    Route::get('/', function () { return "سيتم تلقي جميع المسارات هنا وبالتالي لن يتم التعرف على المجموعة."; }); Route::group(['domain' => 'admin.localhost'], function () { Route::get('/', function () { return "وبالتالي هذه المجموعة لن تكون مرئية للرافيل"; }); });  
  14. إجابة Sam Ahw سؤال في الوصول إلى قيم env ضمن مكونات inertia في لارافيل كانت الإجابة المقبولة   
    عند تعريف القيم ومحاولة الوصول لها ضمن مكونات Vue يجب إضافة القيم ضمن AppServiceProvider أيضاً بالشكل التالي:
    Inertia::share('appName', config('app.name')); حيث يمكن استخدام config أو env ثم ضمن المكوّن يتم الاستدعاء بوضع $inertia متبوعة باسم المتحول كالتالي:
    {{ $inertia.page.props.appName }} ويتم تعريف المتحولات ضمن مصفوفة Array على شكل مفاتيح وقيم، بحيث كل مفتاح يشير إلى قيمة المتحول الموجودة ضمن ملف env بالشكل التالي:
    Inertia::share(function () { return [ 'app' => [ 'name' => config('app.name'), ], ]; }); بحيث يمكن استدعائها مباشرة كالتالي:
    <template> <div> App name: {{ $page.app.name }} </div> </template>  
  15. إجابة Sam Ahw سؤال في كيفية إضافة inertia في لارافيل كانت الإجابة المقبولة   
    إن @inertia تعمل ولكن لا يستطيع لارافيل تحميلها ضمن الصفحة لأنه يجب عليك تحميل adapter الخاص بها. عن طريق:
    npm install @inertiajs/inertia @inertiajs/inertia-vue ثم يجب إعداد webpack ضمن المشروع على الشكل التالي (webpack.mix.js):
    const mix = require('laravel-mix') const path = require('path') mix.js('resources/js/app.js', 'public/js') .webpackConfig({ output: { chunkFilename: 'js/[name].js?id=[chunkhash]' }, resolve: { alias: { vue$: 'vue/dist/vue.runtime.esm.js', '@': path.resolve('resources/js'), }, }, }) وأيضاً تهيئة Vue ضمن الملف الرئيسي (resources/js/app.js) .
    بحيث يتم إضافة InertiaApp من المكتبة inertia-vue في رأس الصفحة:
    import { InertiaApp } from '@inertiajs/inertia-vue' import Vue from 'vue' Vue.use(InertiaApp) const app = document.getElementById('app') const pages = { 'Auth/Login': require('./Pages/Auth/Login.vue').default, } new Vue({ render: h => h(InertiaApp, { props: { initialPage: JSON.parse(app.dataset.page), resolveComponent: name => pages[name], }, }), }).$mount(app)  
  16. إجابة Sam Ahw سؤال في تغيير مسار composer في نظام ubuntu لارافيل كانت الإجابة المقبولة   
    لوضع المجلد ضمن هذا المسار يمكنك استخدام الأمر التالي:
    export PATH="$PATH:$HOME/.composer/vendor/bin" والذي يقوم بدوره بإضافة المجلد إلى المسار PATH الأساسي الموجود. وهو متاح فقط للجلسة الحالية للمستخدم الحالي على النظام.
    أما في حال أردت بأن يتم تحديدها بشكل أوتوماتيكي فباستخدام bash يمكنك تنفيذ التالي:
    echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc وللتأكد من أن الأمر تم بشكل صحيح، يمكنك تنفيذ التالي:
    source ~/.bashrc ملاحظة: للنسخ الحديثة من لارافيل، يجب أن تقوم بالتأكد من وضع المسار التالي ضمن PATH الخاص بك:
    $HOME/.config/composer/vendor/bin أما عند إنشاء مشروع جديد مختلف عن المشروع القديم، يمكن اختصار السابق بتنفيذ الأمر التالي فقط:
    curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer  
  17. إجابة Sam Ahw سؤال في ما هي لغة ال PHP كانت الإجابة المقبولة   
    باختصار، إن لغة PHP  اختصاراً ل (Hypertext Pre Processor) هي واحدة من أشهر لغات البرمجة التي يتم استخدامها في إنشاء مواقع الويب (من طرف خادم الويب).
    حيث يقوم خادم الويب بتفسير و تنفيذ الكود الخاص بها ثم يرسل النتيجة ليتم عرضها في متصفح المستخدم، و تستخدم لغة PHP لإنشاء صفحات ويب ديناميكية أي صفحات متغيرة المحتوى حيث تتعامل PHP مع قواعد البيانات وجميع العمليات الأخرى التي يتم تنفيذها على خادم الويب.
    من أهم ميزاتها:
    السهولة هي أهم مميزات لغة “php” حيث تعتبر من أسهل اللغات البرمجية و تعتبر الافضل لدي المطورين للويب و خصوصا لمن يتقن لغات برمجية أخري مثل السي و البيرل و حتي لمن ليس لديه خبرة فهي سهلة التعلم . تتوافق مع العديدة من الانظمة بالرغم من انها تحتوي علي نسخ متعددة، و تعمل كل منها في بيئات مختلفة و لكن النسخ جميعها تنبث من نواة أصلية مما يجعلها تنفذ السكريبتات بنفس الطريقة . تحتوي علي ملف إعدادت مما يسمح بالتحكم بالمزايا و الخصائص التي توفرها و هذا يوفر نوع من الحماية و الأمان في الاستخدام وكذلك السهولة في التخصيص لكل مشروع أو موقع الكتروني.  تتميز أيضا بالمرونة و القابلية للتوسع فيمكن للمبرمج الاضافة عليها بواسطة لغات برمجية أخرى، وذلك بفضل شفرتها البرمجية المفتوحة . تحتوي علي العديد من المزايا الاضافية حيث ان يوجد بها دوال معالجات حسابية و رياضية، وتوفر الوصول الي مزودات بيانات مختلفة مثل سي كيو إل وغيرها .  إلى جانب هذه المميزات فهي تتميز ايضا بالسرعة الكبيرة في إنشاء البرامج . ويضاف إلى ذلك الدليل على قوة ومتانة هذه اللغة هو بأن أشهر نظم إدارة المحتوى مبنية بلغة PHP مثل wordpress , Joomla, Drupal وغيرها. أخيراً، لا يمكن القول بأنها تستخدم أكثر من أي لغة أخرى، فتبعاً للعديد من المصادر الرسمية نجد python ولغات برمجة أخرى تتفوق بنسبة الاستخدام على PHP
    ولمزيد من المعلومات حول اللغة واستخداماتها يمكنك البحث على الانترنت ومراجعة التوثيق الرسمي للغة عبر الموقع الرسمي ل PHP.
  18. إجابة Sam Ahw سؤال في إنشاء أحداث خاصة مع استخدام websockets في لارافيل كانت الإجابة المقبولة   
    تتيح websockets في لارافيل إنشاء أحداث خاصة بدءً من إنشاء الاتصال وحتى إنهائه عن طريق استخدام Ratchet:
    Ratchet\WebSocket\MessageComponentInterface. حيث ستمكنك من استخدام onOpen - onClose - onError - onMessage لكل اتصال يتم إنشاؤه مع أي مستخدم، حيث تصبح بالشكل التالي:
    namespace App; use Ratchet\ConnectionInterface; use Ratchet\RFC6455\Messaging\MessageInterface; use Ratchet\WebSocket\MessageComponentInterface; class MyCustomWebSocketHandler implements MessageComponentInterface { public function onOpen(ConnectionInterface $connection) { // TODO: Implement onOpen() method. } public function onClose(ConnectionInterface $connection) { // TODO: Implement onClose() method. } public function onError(ConnectionInterface $connection, \Exception $e) { // TODO: Implement onError() method. } public function onMessage(ConnectionInterface $connection, MessageInterface $msg) { // TODO: Implement onMessage() method. } } وأيضاً يمكن دمجها مع WebSocketsRouter facade للحصول على الأحداث في صفحة أو route محدد في لارافيل.
    حيث يتم استخدام مسارات محددة ضمن routes/web.php بالشكل التالي:
    WebSocketsRouter::webSocket('/my-websocket', \App\MyCustomWebSocketHandler::class);  
  19. إجابة Sam Ahw سؤال في مشكلة Unable to determine linked PHP لارافيل Valet كانت الإجابة المقبولة   
    إن Laravel Valet يقوم بإنشاء ما يدعى بـ symlinks ضمن المسار التالي على نظام لينكس:
    /usr/local/bin ويمكن إنشاء أول رابط عن طريق تنفيذ الأمر التالي:
    brew link php7 حيث سيتم طباعة رسالة النجاح أو الفشل مع تحديد المشكلة في حال وجودها لتتمكن من معرفة السبب بدقة.
    غالباً تكون المشكلة في الصلاحيات الموجودة، للتأكد يجب القيام بالتالي:
    sudo chown -R `whoami`:admin /usr/local/bin ثم:
    lrwxr-xr-x 1 YOURUSER admin 29 10 May 21:40 php -> /usr/local/Cellar/php7/7.1/bin/php (مع استبدال نسخة PHP بالنسخة الموجودة في النظام).
    ولمعرفة نسخة PHP الموجودة نقوم بتنفيذ الأمر:
    brew list وبعدها يمكن إجراء override من جديد على هذه النسخة للقيام بإنشاء link :
    brew link php@7.1 --force --overwrite وأخيراً، نقوم بالتحميل من جديد:
    valet install  
  20. إجابة Sam Ahw سؤال في مشكلة dd limitation في لارافيل كانت الإجابة المقبولة   
    في نسخ لارافيل ماقبل 5.0 كان التابع dd بهذا الشكل:
    function dd() { array_map(function($x) { var_dump($x); }, func_get_args()); die; } ولكن بدءً من النسخة 5 وما فوق أصبح بالشكل التالي:
    function dd() { array_map(function ($x) { (new Dumper)->dump($x); }, func_get_args()); die(1); } بما أن Dumper يستخدم Symfony VarCloner وبالتالي AbstractCloner وهذا الصف بدوره له قيمة $maxItems تساوي بشكل افتراضي 2500.
    وفي حال كان لديك 17 عنصر في كل مصفوفة، إن ناتج الضرب ب 147 = 2499 ولذلك المصفوفة بعد العنصر 147 يتم إزالة مقطعها الأخير أي العناصر الأبناء.
    في حال أردت زيادة القيمة الافتراضية لصف Dumper، يمكن ذلك بعمل Override له كالتالي:
    public function dump($value) { if (class_exists(CliDumper::class)) { $dumper = 'cli' === PHP_SAPI ? new CliDumper : new HtmlDumper; $cloner = new VarCloner(); $cloner->setMaxItems(5000); $dumper->dump($cloner->cloneVar($value)); } else { var_dump($value); } } ومن إحدى الحلول الأخرى، نقوم بإنشاء صف مساعد جديد helper وتضمينه في bootstrap:
    use Illuminate\Support\Debug\HtmlDumper; use Symfony\Component\VarDumper\Cloner\VarCloner; use Symfony\Component\VarDumper\Dumper\CliDumper; function ddd() { $args = func_get_args(); $defaultStringLength = -1; $defaultItemNumber = -1; $defaultDepth = -1; foreach ($args as $variable) { $dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper(); $cloner = new VarCloner(); $cloner->setMaxString($defaultStringLength); $cloner->setMaxItems($defaultItemNumber); $dumper->dump($cloner->cloneVar($variable)->withMaxDepth($defaultDepth)); } die(1); }  
  21. إجابة Sam Ahw سؤال في طباعة رسائل الخطأ Valet في لارافيل كانت الإجابة المقبولة   
    يمكن إيجاد ملف الإعدادات للموقع الخاص بك، عن طريق terminal كالتالي:
    cd ~/.config/valet/Nginx أما للوصول للإعدادات الرئيسية في nginx الخاصة ب valet، فيتم التوجه لها عن طريق:
    cd /usr/local/etc/nginx/valet حيث يمكن تغييرها ضمن الملف valet.conf
    أما لتغيير مكان الطباعة فيجب تغيير السطرين التاليين إلى المكان المناسب الذي سيتم فيه طباعة الرسائل:
    access_log "/Users/[user_id]/.config/valet/Log/access.log"; error_log "/Users/[user_id]/.config/valet/Log/nginx-error.log"; حيث يتم استبدال user_id بالمستخدم المسجّل دخوله إلى النظام.
    وبعدها يجب إعادة التشغيل لضمان حفظ الإعدادات الجديدة:
    valet restart sudo systemctl restart nginx  
  22. إجابة Sam Ahw سؤال في Syntax error or access violation في لارافيل كانت الإجابة المقبولة   
    إنك تحوال جمع group by عامود واحد في الجدول. الحل المختصر للمشكلة بالتوجه إلى ملف config\database.php وتعديل التالي:
    'strict' => false وبذلك يمكنك إجراء group by بدون ظهور هذه المشكلة في حال كان هذا الاستعلام الوحيد الذي يمكنك القيام به ولا يوجد بديل له.
    أو يمكنك تعديل نفس الملف كالتالي:
    'mysql' => [ ... .... 'strict' => true, 'modes' => [ //'ONLY_FULL_GROUP_BY', // الغاء هذه الخاصية سيسمح لك بالجمع عن طريق عمود واحد 'STRICT_TRANS_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'ERROR_FOR_DIVISION_BY_ZERO', 'NO_AUTO_CREATE_USER', 'NO_ENGINE_SUBSTITUTION' ], ] ولكن من غير المرجّح تغيير القيمة 'strict' => false لضرورات أمنية في لارافيل ولتجنب بقية المشاكل في المستقبل.
    لذلك، يمكنك فصل الاستعلام السابق إلى مرحلتين عن طريق اجراء get() أولاً، ثم groupBy('answer_no) كالتالي:
    $load_id = explode("#@*", $answers->loading_id); $loading_data = DB::table('loading')->whereIn('id', $load_id)->get(); $grouped = $loading_data->groupBy('answer_no');  
  23. إجابة Sam Ahw سؤال في كيفية استخدام mongodb مع لارافيل lumen كانت الإجابة المقبولة   
    أولاً يجب تحميل الإضافة الخاصة بـ PHP ليستطيع التعامل مع Mongodb بتعديل ملف php.ini وإضافة السطر التالي:
    extension=mongo.so ويكن أيضاً تحميله بشكل يدوي كالتالي:
    Installing '/usr/lib/php/extensions/no-debug-non-zts-20060613/mongo.so' ولمزيد من المعلومات حول ذلك يمكنك الاطلاع على الإضافة الخاصة ب mongodb في التوثيق الرسمي ل PHP.
    بعد ذلك، يجب التوجه إلى مجلّد المشروع الرئيسي وتنفيذ الأمر التالي:
    composer require jenssegers/mongodb وبعدها يجب إضافة المزوّد الخاص بها قبل تعريف Facades أو Eloquent وإلا لن تعمل بالشكل المطلوب:
    $app->register(Jenssegers\Mongodb\MongodbServiceProvider::class); $app->withFacades(); $app->withEloquent(); وأخيراً، يجب تحميل الإعدادات تلقائياً وقبل تعريف المسارات نظراً لأن lumen لا يقوم بالتحميل التلقائي لها:
    $app->configure('database'); وعندها يمكن استخدام الاتصال وتعريف المودل كالتالي:
    <?php namespace App; use Jenssegers\Mongodb\Model as Eloquent; class Example extends Eloquent { protected $connection = 'mongodb'; protected $collection = 'example'; protected $primaryKey = '_id'; } كما يوجد حل بديل لما سبق عن طريق تحميل المكتبة التالية:
    composer require nordsoftware/lumen-doctrine-mongodb-odm  
  24. إجابة Sam Ahw سؤال في خطأ 403 Forbidden عند استخدام Telescope في لارافيل كانت الإجابة المقبولة   
    بشكل إفتراضي يعمل تيليسكوب فقط على بيئة التطوير مع حظر الوصول له عند النشر على خادم الويب وتغيير APP_ENV لتصبح جاهزة للنشر.
    ولكن يمكن تعديل ذلك بالتوجه إلى المسار التالي:
    app/Providers/TelescopeServiceProvider.php وتعديل محتوى gate المسؤول عن منع الوصول إلى تيليسكوب وإضافة بعض الحسابات الاستثنائية كالتالي:
    * @return void */ protected function gate() { Gate::define('viewTelescope', function ($user) { return in_array($user->email, [ // المستخدمين المسموح لهم الوصول إليه 'user@yourapp.com', ]); }); } يجب أيضاً إجراء الأمر التالي عند التغيير على قيم .env لتجنب حدوث أي مشاكل:
    php artisan config:cache  
  25. إجابة Sam Ahw سؤال في الحصول على token بعد إعادة تعيين كلمة المرور في لارافيل كانت الإجابة المقبولة   
    يمكن الحصول على token بعد الضغط على الرابط المطلوب عن طريق:
    request::query() بفرض رابط إعادة تعيين كلمة المرور يحوي token كالتالي:
    http://localhost/forgot?c2108023762b4f86029d5758207cb4156fd58052ad9d6b13b729ce84092937de فيكون المسار:
    Route::get('forgot', function (Illuminate\Http\Request $request) { $query = $request->query(); $token = (array_keys($query))[0]; echo $token; // c2108023762b4f86029d5758207cb4156fd58052ad9d6b13b729ce84092937de ويفضّل أيضاً إحاطة الكود الخاص بالمتحكم ب try catch نظراً لإحتمالية حدوث أخطاء أثناء العملية. فيصبح الكود الخاص بالمتحكّم على الشكل التالي:
    public function recover(Request $request) { $user = Admin::where('email', $request->email)->first(); if (!$user) { $error_message = "Your email address was not found."; return redirect()->back()->with(['errors' => $error_message]); } try { Password::sendResetLink($request->only('email'), function (Message $message) { $message->subject('Your Password Reset Link'); }); } catch (\Exception $e) { $error_message = $e->getMessage(); return redirect()->back()->with(['errors' => $error_message]); } return redirect()->back()->with(['success' => 'A reset email has been sent! Please check your email.']); }  
×
×
  • أضف...