لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 02/17/21 في كل الموقع
-
يمكنك إسكات تحذيرات وإلغاء تفعيل SSL عن طريق تعديل الـurl الخاصة بقاعدة البيانات وإضافة useSSL=false و autoReconnect=true حيث ستكون الـurl كالتالي: jdbc:mysql://localhost:2000?autoReconnect=true&useSSL=false2 نقاط
-
يُمكن ذلك بإضافة حقل جديد لجدول المُستخدم banned_until و إستخدام middleware تعمل على منع المُستخدم من تسجيل الدخول إذا كان في فترة توقيف حسابه إضافة الحقل banned_until إلى جدول المستخدمين: php artisan make:migration add_banned_until_to_users_table هذا الأمر سيُنشئ ملف تهجير يُمكننا من إضافة حقل جديد لجدول المستخدمين. class AddBannedUntilToUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { $table->timestamp('banned_until')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('banned_until'); }); } } بعد ذلك نقوم بتنفيذ أمر التهجير: php artisan migrate هذا يعني أن المُستخدم إن كانت banned_until فارغة أي null فإن الحساب نشيط، اما إن كان بالحقل تاريخ مُستقبلي فإن الحساب قد تم إيقافه. نضيف الحقل إلى مصفوفة fillable و مصفوفة dates في النموذج User و ذلك حتى نستطيع مُعاملة الحقل على أنه تاريخ: class User extends Authenticatable { protected $fillable = [ 'name', 'email', 'password', 'banned_until' ]; protected $dates = [ 'banned_until' ]; } نقوم بإنشاء middleware نُسميها CheckBanned بهذا الأمر: php artisan make:middleware CheckBanned سيتم إنشاء الmiddleware في المسار التالي app/Http/Middleware نقوم بفتح الملف و نُعدل على الدالة handle بالشكل التالي: <?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Str; class CheckBanned { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle(Request $request, Closure $next) { if (auth()->check() && auth()->user()->banned_until && now()->lessThan(auth()->user()->banned_until)) { $banned_days = now()->diffInDays(auth()->user()->banned_until); auth()->logout(); $message = 'Your account has been suspended for '.$banned_days.' '.Str::plural('day', $banned_days).'. Please contact administrator.'; return redirect()->route('login')->withMessage($message); } return $next($request); } } تعمل الmiddleware على التحقق من أن المُصادقة تمت أي أن المستخدم أدخل بيانات صحيحة، و أن الحقل banned_until لهذا المُستخدم ليس فارغ و أن الحقل به تاريخ مُستقبلي: إذا تحققت هذه الشروط تقوم بحساب فارق الأيام بين التاريخ الحالي و تاريخ الإيقاف و تقوم بتسجيل خروج للمُستخدم و إعادة توجيهه إلى صفحة تسجيل الخروج مع تمرير الرسالة. يُمكن تمرير رسالة مُختلفة بحسب عدد الأيام كأن نتحقق إن كان عدد الأيام أقل من 20 نعرض عدد الأيام و إذا كان عدد الأيام اكبر لا نعرض عدد الأيام. فقط نقول أن الحساب تم إيقافه و لا نذكر المدة. الأمر راجع لك في هذه النقطة. يتبقى تسجيل هذه الmiddleware و يتم ذلك على مستوى الملف app/Http/Kernel.php في المصفوفة middlewareGroups داخل المصفوفة ذات المفتاح web: protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, // ... other middleware classes \App\Http\Middleware\CheckBanned::class, ], الآن نقوم بعرض الرسالة في حالة كانت موجودة على مستوى صفحة العرض login.blade.php: <div class="card-body"> @if (session('message')) <div class="alert alert-danger">{{ session('message') }}</div> @endif <form method="POST" action="{{ route('login') }}"> ... و هذه النتيجة:2 نقاط
-
بإمكانك إستخدام أمر إنشاء ملف تهجير فملفات التهجير ليست مُخصصة فقط لإنشاء الجداول و إنما تُمكنك أيضاً من إضافة عمود جديد لجدول بيانات أيضاً. لنفترض أننا نريد إضافة عمود age للجدول users فيتم ذلك عن طريق الأمر التالي: php artisan make:migration add_age_to_users_table هذا الأمر سيُنشئ لنا ملف migration جديد و سيحتوي على الصنف التالي: class AddAgeToUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { }); } } الآن نقوم بإضافة العمود في الدالة up و من خلال الدالة down نقوم بحذفه كما هو موضح أدناه: <?php public function up() { Schema::table('users', function (Blueprint $table) { $table->unsignedTinyInteger('age')->nullable()->after('username'); }); } و هذا يعني أننا نريد إضافة العمود age على أنه unsignedTinyInteger إضافة الى أنه سيكون فارغ إفتراضياً و سيُضاف بعد العمود username. أما الدالة down ستكون بهذا الشكل: <?php public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('age'); }); } و بالتالي كل ما عليك الآن هو تنفيذ امر التهجير: php artisan migrate هذا الأمر سيُنفذ الدالة up و يُضيف العمود الجديد. أما الدالة down يتم تنفيذها عند تنفيذ أمر rollback الذي سيحذف العمود age.2 نقاط
-
دوال الملاءمة (Convenience functions) الخرج والدخل الخام المباشر توفر الدالتان file_get_contents و file_put_contents قابلية القراءة/الكتابة إلى/من ملف من/إلى سلسلة نصية في PHP في استدعاء واحد. يمكن أن تستخدم الدالة file_put_contents أيضًا مع راية القناع البتي FILE_APPEND للإضافة إلى الملف بدلًا من الكتابة فوقه، ويمكن استخدامها مع القناع البتي LOCK_EX للحصول على قفل حصري للملف أثناء إجراء الكتابة. يمكن دمج رايات القناع البتي باستخدام عامل العملية الثنائية OR |. $path = "file.txt"; // قراءة محتويات الملف file.txt إلى $contents $contents = file_get_contents($path); // إذا غيّرنا شيئًا ما مثلًا `CRLF` إلى `LF` $contents = str_replace("\r\n", "\n", $contents); // نكتب هذا التغيير في file.txt مستبدلين المحتويات الأصلية file_put_contents($path, $contents); تفيد الراية FILE_APPEND في الإضافة إلى ملفات السجلات، بينما تساعد الراية LOCK_EX في منع حالة سباق عدة عمليات للكتابة في الملف، فمثلًا لكتابة حالة الجلسة الحالية في ملف سجل: file_put_contents("logins.log", "{$_SESSION["username"]} logged in", FILE_APPEND | LOCK_EX); الخرج والدخل بصيغة CSV fgetcsv($file, $length, $separator) تحلل الدالة fgetcsv سطرًا من الملف المفتوح وتبحث عن حقول csv، ثم تعيد هذه الحقول في مصفوفة في حالة النجاح وإلا تعيد FALSE. تقرأ بشكلٍ افتراضي سطرًا واحدًا فقط من ملف csv. $file = fopen("contacts.csv","r"); print_r(fgetcsv($file)); print_r(fgetcsv($file,5," ")); fclose($file); محتويات ملف contacts.csv: Kai Jim, Refsnes, Stavanger, Norway Hege, Refsnes, Stavanger, Norway الخرج: Array ( [0] => Kai Jim [1] => Refsnes [2] => Stavanger [3] => Norway ) Array ( [0] => Hege, ) قراءة ملف إلى مجرى الخرج القياسي مباشرةً تنسخ الدالة readfile ملفًا إلى المخزن المؤقت للخرج، ولا تؤدي إلى ظهور أيّة مشاكل في الذاكرة حتى عند إرسال ملفات كبيرة من تلقاء نفسها. $file = 'monkey.gif'; if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.basename($file).'"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); readfile($file); exit; } القراءة بدءًا من مكان مؤشر في ملف نستخدم الدالة fpassthru بدلًا من ذلك للبحث عن نقطة في الملف للبدء بالنسخ إلى مجرى الخرج القياسي، في المثال التالي يُنسخ آخر 1024 بايت إلى الخرج القياسي: $fh = fopen("file.txt", "rb"); fseek($fh, -1024, SEEK_END); fpassthru($fh); قراءة ملف إلى مصفوفة تعيد الدالة file أسطر الملف الممرَّر في مصفوفة، يقابل كل عنصر من المصفوفة سطرًا من الملف مع استمرار إضافة السطر الجديد. print_r(file("test.txt")); محتويات الملف test.txt: Welcome to File handling This is to test file handling الخرج: Array ( [0] => Welcome to File handling [1] => This is to test file handling ) حذف ملفات ومجلدات حذف ملفات تحذف الدالة unlink ملفًا واحدًا وتعيد القيمة TRUE عند نجاح العملية وFALSE عند فشلها. $filename = '/path/to/file.txt'; if (file_exists($filename)) { $success = unlink($filename); if (!$success) { throw new Exception("Cannot delete $filename"); } } حذف مجلدات مع حذف عودي (recursive deletion) يمكن حذف المجلدات باستخدام الدالة rmdir إلا أنّ هذه الدالة تحذف المجلدات الفارغة فقط، ولحذف مجلد يحتوي ملفات يجب حذف هذه الملفات أولًا، إذا احتوى المجلد على مجلدات فرعية نحتاج إلى استخدام العودية. يفحص المثال التالي الملفات في مجلد ويحذف ما بداخله من ملفات ومجلدات بشكلٍ تعاودي ويعيد عدد الملفات (وليس المجلدات) المحذوفة. function recurse_delete_dir(string $dir) : int { $count = 0; // التأكد من أنّ $dir ينتهي بخط مائل لنتمكن من ربطه مع أسماء الملفات مباشرةً $dir = rtrim($dir, "/\\") . "/"; // استخدام dir() للحصول على قائمة الملفات $list = dir($dir); // تخزين اسم الملف التالي في $file، إذا كانت قيمة $file هي false أي لا توجد ملفات بعد عندها تُنهى الحلقة while(($file = $list->read()) !== false) { if($file === "." || $file === "..") continue; if(is_file($dir . $file)) { unlink($dir . $file); $count++; } elseif(is_dir($dir . $file)) { $count += recurse_delete_dir($dir . $file); } } // يمكننا الآن حذف المجلد rmdir($dir); return $count; } الحصول على معلومات ملف التحقق من كون المسار ملف أو مجلد تتحقق الدالة is_dir إن كان الوسيط الممرر إليها مجلدًا أم لا، فيما تتحقق الدالة is_file إن كان الوسيط الممرر إليها ملفًا أم لا، ويمكن استخدام الدالة file_exists للتحقق من وجود ملف أو مجلد محدد. $dir = "/this/is/a/directory"; $file = "/this/is/a/file.txt"; echo is_dir($dir) ? "$dir is a directory" : "$dir is not a directory", PHP_EOL, is_file($dir) ? "$dir is a file" : "$dir is not a file", PHP_EOL, file_exists($dir) ? "$dir exists" : "$dir doesn't exist", PHP_EOL, is_dir($file) ? "$file is a directory" : "$file is not a directory", PHP_EOL, is_file($file) ? "$file is a file" : "$file is not a file", PHP_EOL, file_exists($file) ? "$file exists" : "$file doesn't exist", PHP_EOL; الخرج: /this/is/a/directory is a directory /this/is/a/directory is not a file /this/is/a/directory exists /this/is/a/file.txt is not a directory /this/is/a/file.txt is a file /this/is/a/file.txt exists التحقق من نوع ملف نستخدم الدالة filetype لمعرفة نوع ملف محدد والذي قد يكون إمَّا أنبوبة مسماة FIFO أو ملف محرفي خاص char أو مجلد dir أو ملف كتلي خاص block أو وصلة رمزية link أو ملف عادي file أو مقبس socket أو نوع غير معروف unknown. تمرير اسم الملف إلى الدالة filetype مباشرةً: echo filetype("~"); // dir لاحظ أنّه إذا لم يكن الملف موجودًا فإنّ الدالة تعيد false وتشغّل E_WARNING. التحقق من قابلية القراءة والكتابة نمرر اسم الملف للدالتين is_writable وis_readable للتحقق من كون الملف قابلًا للكتابة أو القراءة. تعيد الدالتان القيمة false إذا لم يكن الملف موجودًا. التحقق من وقت الوصول إلى ملف وتعديله تعيد الدالتان filemtime وfileatime الختم الزمني لآخر تعديل أو وصول للملف، ويكون الختم الزمني المعاد بصيغة Unix. echo "File was last modified on " . date("Y-m-d", filemtime("file.txt")); echo "File was last accessed on " . date("Y-m-d", fileatime("file.txt")); الحصول على أجزاء المسار مع fileinfo $fileToAnalyze = ('/var/www/image.png'); $filePathParts = pathinfo($fileToAnalyze); echo '<pre>'; print_r($filePathParts); echo '</pre>'; خرج المثال السابق: Array ( [dirname] => /var/www [basename] => image.png [extension] => png [filename] => image ) يمكن استخدام هذا الخرج كالتالي: $filePathParts['dirname'] $filePathParts['basename'] $filePathParts['extension'] $filePathParts['filename'] المعامل تفاصيل $path المسار الكامل للملف الذي نريد تحليله $option أحد الخيارات التالية: PATHINFO_DIRNAME أو PATHINFO_BASENAME أو PATHINFO_EXTENSION أو PATHINFO_FILENAME table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } تُعاد مصفوفة ترابطية (associative array) إذا لم يُمرَّر المعامل الثاني وإلا تُعاد سلسلة نصية. لا تتحقق من وجود الملف تُحلَّل السلسلة النصية ببساطة إلى أجزاء ولا يُجرى أي تحقق على الملف (مثل التحقق من نوع الترويسة وغير ذلك) الامتداد هو الامتداد الأخير للمتغير $path، سيكون مسار الملف image.jpg.png هو .png حتى لو كان هو ملف .jpg تقنيًا، وإذا كان الملف بدون امتداد لن يُعاد عنصر الامتداد في المصفوفة. خرج ودخل ملف معتمد على المجرى فتح مجرى تفتح الدالة fopen ملفًا وتخصص له مقبضًا يشبه مقبض الباب يمكن أن تستخدمه دوالًا أخرى للقراءة والكتابة والبحث وغيرها، هذه القيمة من النوع مورد ولا يمكن تمريرها إلى النياسب الأخرى المستمرة في وظيفتها. $f = fopen("errors.log", "a"); ستحاول الشيفرة السابقة فتح الملف errors.log للكتابة. المعامل الثاني هو نمط مجرى الملف: النمط الوصف r يفتح الملف للقراءة فقط بدءًا من أول الملف r+ يفتح الملف للقراءة والكتابة بدءًا من أول الملف w يفتح الملف للكتابة فقط بدءًا من أول الملف، إذا كان الملف موجودًا سيفرغه وإذا لم يكن موجودًا سيحاول أن ينشئه w+ يفتح الملف للقراءة والكتابه بدءًا من أول الملف، إذا كان الملف موجودًا سيفرغه وإذا لم يكن موجودًا سيحاول أن ينشئه a يفتح الملف للكتابة فقط بدءًا من نهاية الملف، إذا لم يكن الملف موجودًا سيحاول أن ينشئه a+ يفتح الملف للقراءة والكتابة بدءًا من نهاية الملف، إذا لم يكن الملف موجودًا سيحاول أن ينشئه x ينشئ ويفتح ملف للكتابة فقط، وإذا كان الملف موجودًا ستفشل الدالة fopen x+ ينشئ ويفتح ملف للكتابة فقط، وإذا كان الملف موجودًا ستفشل الدالة fopen c يفتح الملف للكتابة فقط، إذا لم يكن موجودًا سيحاول أن ينشئه، يبدأ الكتابة من أول الملف لكنه لا يفرغ الملف قبل الكتابة c+ يفتح الملف للقراءة والكتابة، إذا لم يكن موجودًا سيحاول أن ينشئه، يبدأ الكتابة من أول الملف لكنه لا يفرغ الملف قبل الكتابة إنّ إضافة المحرف t بعد النمط (مثل a+b، wt وغير ذلك) في نظام التشغيل ويندوز ستترجم نهايات الأسطر "\n" إلى "\r\n" عند العمل مع الملف، نضيف المحرف b بعد النمط إذا لم يكن هذا مقصودًا خاصةً إذا كان الملف ثنائيًا. يجب أن يغلق تطبيق PHP أي مجرى بعد الانتهاء من استخدامه باستخدام الدالة fclose وذلك منعًا لظهور الخطأ Too many open files، يعدّ هذا مهمًا خاصةً في برامج واجهة سطر الأوامر (CLI) بما أنّ المجاري تُغلق عند إيقاف التشغيل فقط، وهذا يعني أن ذلك ليس ضروريًا جدًا في خوادم الويب (لكن يجب استخدامه أيضًا كممارسة لمنع تسرب المورد) إذا لم تتوقع تنفيذ العملية لوقتٍ طويل ولن تفتح عدة مجاري. القراءة نستخدم الدالة fread لقراءة عدد مُعطى من البايتات بدءًا من مؤشر الملف أو حتى الوصول إلى نهاية الملف (EOF). قراءة أسطر نستخدم الدالة fgets لقراءة ملف وتستمر بالقراءة حتى تصل إلى نهاية السطر (EOL) أو حتى تنتهي قراءة العدد المُعطى. ستحرِّك كل من الدالتين fread وfgets مؤشر الملف أثناء القراءة. قراءة كل البايتات المتبقية تضع الدالة stream_get_contents كل البايتات المتبقية في المجرى في سلسلة نصية وتعيدها. تعديل موضع مؤشر ملف يكون مؤشر الملف عند فتح المجرى افتراضيًا في بداية الملف (أو في نهايته إذا اُستعمل النمط)، نستخدم الدالة fseek لنحرّك مؤشر الملف إلى موضع جديد، نسبةً لإحدى القيم الثلاثة: SEEK_SET: هذه هي القيمة الافتراضية، تكون إزاحة موقع مؤشر الملف نسبةً لبدايته. SEEK_CUR: إزاحة موقع مؤشر الملف نسبةً للموقع الحالي. SEEK_END: إزاحة موقع مؤشر الملف نسبةً إلى نهاية الملف، ومن الشائع تمرير إزاحة سالبة لهذه القيمة، ستحرّك موقع مؤشر الملف عددًا محددًا من البايتات قبل نهاية الملف. تعد الدالة rewind اختصارًا ملائمًا للشيفرة fseek($fh, 0, SEEK_SET). يُظهر استخدام الدالة ftell الموقع المطلق لمؤشر الملف. يتخطى السكربت التالي أول 10 بايتات، ويقرأ 10 بايتات التالية ثم يتخطى 10 بايتات ويقرأ 10 بايتات ثم يقرأ 10 بايتات الأخيرة من الملف file.txt: $fh = fopen("file.txt", "rb"); // البدء من الإزاحة 10 fseek($fh, 10); // قراءة 10 بايتات echo fread($fh, 10); // تخطي 10 بايتات fseek($fh, 10, SEEK_CUR); // قراءة 10 بايتات echo fread($fh, 10); // تخطي 10 بايتات قبل نهاية الملف fseek($fh, -10, SEEK_END); // قراءة 10 بايتات echo fread($fh, 10); fclose($fh); الكتابة نستخدم الدالة fwrite لكتابة سلسلة في ملف بدءًا من موقع المؤشر الحالي. fwrite($fh, "Some text here\n"); نقل ونسخ ملفات ومجلدات نسخ ملفات تنسخ الدالة copy الملف المصدر المحدد في الوسيط الأول إلى الهدف المحدد في الوسيط الثاني، يجب أن يكون الهدف في مجلد مُنشأ بالفعل. if (copy('test.txt', 'dest.txt')) { echo 'File has been copied successfully'; } else { echo 'Failed to copy file to destination given.' } نسخ مجلدات مع عودية (recursion) يشبه نسخ الملفات حذفها إلى درجة كبيرة، باستثناء أننا نستخدم الدالة copy بدلًا من unlink للملفات وmkdir بدلًا من rmdir للمجلدات في بداية بدلًا من كونها في نهاية الدالة. function recurse_delete_dir(string $src, string $dest) : int { $count = 0; // التأكد من أنّ كل من $src و$dest ينتهي بخط مائل حتى يمكننا دمجه مع أسماء الملفات $src = rtrim($dest, "/\\") . "/"; $dest = rtrim($dest, "/\\") . "/"; // استخدام dir() للحصول على قائمة الملفات $list = dir($src); // إنشاء المجلد $dest إذا لم يكن موجودًا @mkdir($dest); // تخزين اسم الملف التالي في $file، إذا أصبحت قيمة $file هي false تُنهى الحلقة while(($file = $list->read()) !== false) { if($file === "." || $file === "..") continue; if(is_file($src . $file)) { copy($src . $file, $dest . $file); $count++; } elseif(is_dir($src . $file)) { $count += recurse_copy_dir($src . $file, $dest . $file); } } return $count; } إعادة التسمية/النقل عملية إعادة التسمية/النقل أبسط بكثير، إذ يمكن نقل أو إعادة تسمية كامل المجلد في استدعاء واحد للدالة rename، أمثلة: rename("~/file.txt", "~/file.html"); rename("~/dir", "~/old_dir"); rename("~/dir/file.txt", "~/dir2/file.txt"); تقليل استخدام الذاكرة عند التعامل مع ملفات كبيرة يمكننا استخدام إحدى الدالتين file أو file_get_contents إذا احتجنا إلى تحليل ملف كبير مثل ملف CSV يتضمن ملايين الأسطر وحجمه أكبر من 10 ميجابايت وينتهي الأمر بالحصول على الخطأ: Allowed memory size of XXXXX bytes exhausted بفرض أنّ المصدر التالي top-1m.csv يحتوي على مليون سطر وحجمه حوالي 22 ميجابايت. var_dump(memory_get_usage(true)); $arr = file('top-1m.csv'); var_dump(memory_get_usage(true)); الخرج: int(262144) int(210501632) بما أنّ المفسّر يحتاج إلى حمل الأسطر في مصفوفة $arr لذا فإنّه يستهلك 200 ميجابايت من ذاكرة الوصول العشوائي (RAM)، لاحظ أنّه لا يمكننا فعل أي شيء مع محتويات المصفوفة. بفرض أنّه لدينا الشيفرة التالية: var_dump(memory_get_usage(true)); $index = 1; if (($handle = fopen("top-1m.csv", "r")) !== FALSE) { while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) { file_put_contents('top-1m-reversed.csv',$index . ',' . strrev($row[1]) . PHP_EOL,FILE_APPEND); $index++; } fclose($handle); } var_dump(memory_get_usage(true)); خرج الشيفرة السابقة: int(262144) int(262144) لا نستخدم بايتًا واحدًا إضافيًا من الذاكرة لكن نحلل كامل ملف CSV ونحفظه إلى ملف آخر مع عكس قيمة العمود الثاني، وذلك لأنّ الدالة fgetcsv تقرأ سطر واحد فقط ويُكتب فوق $row عند كل تكرار. المجاري (streams) اسم المعامل الوصف Stream Resource يتألف مزود البيانات من الصيغة `://` تسجيل مغلِّف مجرى يوفر مغلِّف المجرى مقبضًا لمخطط محدد أو أكثر، يُظهر المثال التالي مُغلِّف مجرى بسيط يرسل طلبات PATCH HTTP عند إغلاق المجرى. // تسجيل الصنف FooWrapper مغلِّفًا لمجرى روابط foo:// stream_wrapper_register("foo", FooWrapper::class, STREAM_IS_URL) or die("Duplicate stream wrapper registered"); class FooWrapper { // سيُعدَّل هذا من PHP لإظهار السياق الممرَّر في الاستدعاء الحالي public $context; // يستخدم هذا داخليًا في هذا المثال لتخزين الرابط private $url; // عند استدعاء fopen() مع بروتوكول لهذا المغلِّف، يمكن تنفيذ هذا التابع لتخزين بيانات مثل المضيف. public function stream_open(string $path, string $mode, int $options, string &$openedPath) :bool { $url = parse_url($path); if($url === false) return false; $this->url = $url["host"] . "/" . $url["path"]; return true; } // معالجة استدعاءات الدالة fwrite() على هذا المجرى public function stream_write(string $data) : int { $this->buffer .= $data; return strlen($data); } // معالجة استدعاءات الدالة fclose() على هذا المجرى public function stream_close() { $curl = curl_init("http://" . $this->url); curl_setopt($curl, CURLOPT_POSTFIELDS, $this->buffer); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH"); curl_exec($curl); curl_close($curl); $this->buffer = ""; } // مُعالج استثناء قيمة تراجعية في حال القيام بعملية غير مدعومة // هذا ليس ضروريًا public function __call($name, $args) { throw new \RuntimeException("This wrapper does not support $name"); } // تُستدعى الشيفرة التالية عند استدعاء unlink("foo://something-else") public function unlink(string $path) { $url = parse_url($path); $curl = curl_init("http://" . $url["host"] . "/" . $url["path"]); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_exec($curl); curl_close($curl); } } يُظهر هذا المثال بعض الأمثلة على ما قد يحتويه مُغلِّف مجرى عام، ليست هذه كل التوابع المتوفرة، يمكنك أن تجد هنا كل التوابع المتوفرة والتي يمكن تنفيذها. ترميز UTF-8 الدخل يجب التحقق من كل سلسلة نصية مُستقبَلة أنّها مكتوبة بترميز UTF-8 صحيح قبل محاولة تخزينها في أي مكان، تقوم دالة mbcheckencoding() بهذا العمل لكن يجب أن تستخدمها بشكلٍ منتظم، لا توجد طريقة لحل هذه المشكلة إذ يمكن للعملاء الضارّين إرسال البيانات بأي تشفير يريدونه. $string = $_REQUEST['user_comment']; if (!mb_check_encoding($string, 'UTF-8')) { // ترميز السلسلة النصية ليس UTF-8 لذا أعد تشفيرها $actualEncoding = mb_detect_encoding($string); $string = mb_convert_encoding($string, 'UTF-8', $actualEncoding); } يمكنك تجاهل النقطة الأخيرة إذا كنت تستخدم HTML5، إذ أنّ الطريقة الموثوقة الوحيدة لتكون كل البيانات المرسلة إليك عبر المتصفحات بالترميز UTF-8 هي إضافة السمة accept-charset لكل وسوم <form> كالتالي: <form action="somepage.php" accept-charset="UTF-8"> الخرج إذا كان تطبيقك ينقل نصًا إلى الأنظمة الأخرى فأنت تحتاج إلى التأكد من ترميز المحارف، يمكنك في PHP استخدام خيار default_charset في php.ini أو التصريح عن نوع المحتوى يدويًا Content-Type MIME في الترويسة وهذه الطريقة الأفضل عند استهداف المتصفحات الحديثة. header('Content-Type: text/html; charset=utf-8'); يمكنك ضبط الترميز في ملف HTML باستخدام البيانات الوصفية إذا كنت غير قادرٍ على ضبط ترويسة الرد. // HTML5 <meta charset="utf-8"> // الإصدارات الأقدم من HTML <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> تخزين البيانات والوصول إليها تتحدث هذه الفقرة بشكلٍ أساسي عن الترميز UTF-8 ودوافع استخدامه مع قاعدة البيانات. تخزين البيانات في قاعدة بيانات MySQL: عندما تحدد مجموعة المحارف (character set) utf8mb4 لكل الجداول والأعمدة النصية في قاعدة البيانات فأنت تجعل MySQL تخزّن وتستعيد القيم المرمّزة محليًا بالترميز UTF-8. تستخدم MySQL ضمنيًا الترميز utf8mb4 إذا حُدِّد الترتيب utf8mb4_* (دون أي مجموعة محارف صريحة). لا تدعم النسخ القديمة من MySQL (الإصدار ما قبل 5.5.3) الترميز utf8mb4 لذا ستضطر إلى استخدام الترميز utf8 الذي يدعم مجموعة فرعية من محارف يونيكود (Unicode). الوصول إلى البيانات في قاعدة بيانات MySQL: في شيفرة التطبيق (PHP مثلًا)، مهما كانت الطريقة التي تستخدمها للوصول إلى قاعدة البيانات فأنت تحتاج إلى ضبط ترميز محارف الاتصال لتكون utf8mb4، بهذه الطريقة لا تحوّل MySQL من ترميز UTF-8 الأصلي عند تسليم البيانات إلى تطبيقك وبالعكس. توفر بعض برامج التشغيل آلية خاصة بها لضبط ترميز محارف الاتصال والتي تحدّث حالتها الداخلية وتُخبر MySQL بالترميز الذي سيُستخدم في الاتصال، وهذه هي الطريقة المفضّلة عادةً. مثلًا (نطبق نفس الدوافع التي في الأعلى فيما يتعلق باستخدام utf8mb4/utf8😞 يمكنك تحديد ترميز المحارف باستخدام DSN إذا كنت تستخدم طبقة التجريد PDO مع إصدار PHP ≥ 5.3.6: $handle = new PDO('mysql:charset=utf8mb4'); يمكنك استدعاء الدالة set_charset() إذا كنت تستخدم mysqli: $conn = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db'); // نمط كائني التوجه $conn->set_charset('utf8mb4'); // نمط إجرائي mysqli_set_charset($conn, 'utf8mb4'); يمكنك استدعاء الدالة mysql_set_charset إذا كنت تستخدم MySQL البسيطة وإصدار PHP ≥ 5.2.3. $conn = mysql_connect('localhost', 'my_user', 'my_password'); // نمط كائني التوجه $conn->set_charset('utf8mb4'); // نمط إجرائي mysql_set_charset($conn, 'utf8mb4'); إذا لم يوفر نظام تشغيل قاعدة البيانات آلية خاصة به لضبط ترميز محارف الاتصال، قد تضطر إلى إصدار استعلام لإخبار MySQL عن الطريقة التي يتوقع بها تطبيقك تشفير البيانات عند الاتصال بالشكل: SET NAMES 'utf8mb4'. دعم يونيكود في PHP تحويل محارف يونيكود إلى تنسيق "\uxxxx" باستخدام PHP يمكنك استخدام الشيفرة التالية للترميز وفك الترميز: if (!function_exists('codepoint_encode')) { function codepoint_encode($str) { return substr(json_encode($str), 1, -1); } } if (!function_exists('codepoint_decode')) { function codepoint_decode($str) { return json_decode(sprintf('"%s"', $str)); } } طريقة الاستخدام echo "\\nUse JSON encoding / decoding\\n"; var_dump(codepoint_encode("我好")); var_dump(codepoint_decode('\\u6211\\u597d')); الخرج: Use JSON encoding / decoding string(12) "\\u6211\\u597d" string(6) "我好" تحويل محارف يونيكود إلى قيمها الرقمية و/أو كيانات HTML باستخدام PHP يمكنك استخدام الشيفرة التالية للترميز وفك الترميز: if (!function_exists('mb_internal_encoding')) { function mb_internal_encoding($encoding = NULL) { return ($from_encoding === NULL) ? iconv_get_encoding() : iconv_set_encoding($encoding); } } if (!function_exists('mb_convert_encoding')) { function mb_convert_encoding($str, $to_encoding, $from_encoding = NULL) { return iconv(($from_encoding === NULL) ? mb_internal_encoding() : $from_encoding,$to_encoding, $str); } } if (!function_exists('mb_chr')) { function mb_chr($ord, $encoding = 'UTF-8') { if ($encoding === 'UCS-4BE') { return pack("N", $ord); } else { return mb_convert_encoding(mb_chr($ord, 'UCS-4BE'), $encoding, 'UCS-4BE'); } } } if (!function_exists('mb_ord')) { function mb_ord($char, $encoding = 'UTF-8') { if ($encoding === 'UCS-4BE') { list(, $ord) = (strlen($char) === 4) ? @unpack('N', $char) : @unpack('n', $char); return $ord; } else { return mb_ord(mb_convert_encoding($char, 'UCS-4BE', $encoding), 'UCS-4BE'); } } } if (!function_exists('mb_htmlentities')) { function mb_htmlentities($string, $hex = true, $encoding = 'UTF-8') { return preg_replace_callback('/[\x{80}-\x{10FFFF}]/u', function ($match) use ($hex) { return sprintf($hex ? '&#x%X;' : '&#%d;', mb_ord($match[0])); }, $string); } } if (!function_exists('mb_html_entity_decode')) { function mb_html_entity_decode($string, $flags = null, $encoding = 'UTF-8') { return html_entity_decode($string, ($flags === NULL) ? ENT_COMPAT | ENT_HTML401 : $flags,$encoding); } } طريقة الاستخدام echo "Get string from numeric DEC value\n"; var_dump(mb_chr(50319, 'UCS-4BE')); var_dump(mb_chr(271)); echo "\nGet string from numeric HEX value\n"; var_dump(mb_chr(0xC48F, 'UCS-4BE')); var_dump(mb_chr(0x010F)); echo "\nGet numeric value of character as DEC string\n"; var_dump(mb_ord('ď', 'UCS-4BE')); var_dump(mb_ord('ď')); echo "\nGet numeric value of character as HEX string\n"; var_dump(dechex(mb_ord('ď', 'UCS-4BE'))); var_dump(dechex(mb_ord('ď'))); echo "\nEncode / decode to DEC based HTML entities\n"; var_dump(mb_htmlentities('tchüß', false)); var_dump(mb_html_entity_decode('tchüß')); echo "\nEncode / decode to HEX based HTML entities\n"; var_dump(mb_htmlentities('tchüß')); var_dump(mb_html_entity_decode('tchüß')); الخرج: Get string from numeric DEC value string(4) "ď" string(2) "ď" Get string from numeric HEX value string(4) "ď" string(2) "ď" Get numeric value of character as DEC int int(50319) int(271) Get numeric value of character as HEX string string(4) "c48f" string(3) "10f" Encode / decode to DEC based HTML entities string(15) "tchüß" string(7) "tchüß" Encode / decode to HEX based HTML entities string(15) "tchüß" string(7) "tchüß" استخدام الإضافة Intl لدعم يونيكود تُربط دوال السلسلة النصية الأصلية إلى دوال البايت المفرد ولا تعمل بشكلٍ جيد مع ترميز يونيكود (unicode)، توفر الإضافات iconv وmbstring بعض الدعم لترميز يونيكود بينما توفر الإضافة Intl الدعم الكامل. تعدّ الإضافة Intl مغلّفة للمعيار المعتمد لمكتبة ICU (International Components for unicode)، يمكنك الاطلاع على الموقع لمعرفة المزيد من المعلومات التفصيلية غير الموجودة هنا. اطّلع على تنفيذ بديل للإضافة Intl من بيئة العمل Symfony إذا لم تتمكن من تثبيت الإضافة. توفر ICU تدويلًا كاملًا وترميز يونيكود هو جزء صغير منه، يمكنك التحويل بسهولة: // إزالة البايتات السيئة للحماية من الهجمات \UConverter::transcode($sString, 'UTF-8', 'UTF-8'); لكن يجب ألا تتخلى عن الإضافة iconv: \iconv('UTF-8', 'ASCII//TRANSLIT', "Cliënt"); // "Client" ترجمة -وبتصرف- للفصول [File handling - Streams - UTF-8 - Unicode Support in PHP] من كتاب PHP Notes for Professionals book اقرأ أيضًا المقال التالي: المرشحات ودوال المرشح (Filter) المعقمة في PHP المقال السابق: التوابع السحرية (Magic Methods) في PHP1 نقطة
-
السلام عليكم هل يوجد طريقة اعرض صور في موقعي الشخصي عن طريقة استرجاع صور مضافة من my sql في لغة php؟1 نقطة
-
لدي البيانات التالية كـJSON: [ { "id": 1, "name": "Leanne Graham", "username": "Bret", "email": "Sincere@april.biz", "address": { "street": "Kulas Light", "suite": "Apt. 556", "city": "Gwenborough", "zipcode": "92998-3874", "geo": { "lat": "-37.3159", "lng": "81.1496" } }, "phone": "1-770-736-8031 x56442", "website": "hildegard.org", "company": { "name": "Romaguera-Crona", "catchPhrase": "Multi-layered client-server neural-net", "bs": "harness real-time e-markets" } }, { "id": 2, "name": "Ervin Howell", "username": "Antonette", "email": "Shanna@melissa.tv", "address": { "street": "Victor Plains", "suite": "Suite 879", "city": "Wisokyburgh", "zipcode": "90566-7771", "geo": { "lat": "-43.9509", "lng": "-34.4618" } }, "phone": "010-692-6593 x09125", "website": "anastasia.net", "company": { "name": "Deckow-Crist", "catchPhrase": "Proactive didactic contingency", "bs": "synergize scalable supply-chains" } }, { "id": 3, "name": "Clementine Bauch", "username": "Samantha", "email": "Nathan@yesenia.net", "address": { "street": "Douglas Extension", "suite": "Suite 847", "city": "McKenziehaven", "zipcode": "59590-4157", "geo": { "lat": "-68.6102", "lng": "-47.0653" } }, "phone": "1-463-123-4447", "website": "ramiro.info", "company": { "name": "Romaguera-Jacobson", "catchPhrase": "Face to face bifurcated interface", "bs": "e-enable strategic applications" } } ] كيف احول هذا البيانات إلى Object ؟1 نقطة
-
مرحبا @كمال محمودي يمكنك اضافة column جديد لجدول الخاص ب Users وليكن block_date كتابة هذا اﻷمر في terminal php artisan make:migration add_block_date_to_users_table --table=users public function up() { Schema::table('users', function($table) { $table->date('block_date')->nullable()); // dateTime also // nullable قيم سابقة لابد ان تكون null }); } and don't forget to add the rollback option: public function down() { Schema::table('users', function($table) { $table->dropColumn('block_date'); }); } ثم عمل condition بسيط لو user له block_date و لا تساوي null تقوم بإظهار الرسالة له . يمكنك استخدم القيمة المخزنة في block_date لكي تنبه مستخدم أن تم منعه لمدة معينة باستخدام block_date1 نقطة
-
يوجد الكثير من المواقع التي يمكننا الحصول منها على صور للتصاميم، مثل: unsplash pexels istock shutterstock burst و غيرها الكثير. للحصول على أيقونات و رسومات توضيحية يمكنك استخدام: flaticon undraw craftwork و غيرها. للحصول على مصادر إلهام لتصميماتك يمكنك استخدام: dribbble behance Pinterest land-book و غيرها الكثير و لكن ما ذكرته لك هو الأهر. يمكنك الوصول لهذه المواقع بسهولة عن طريق البحث عنها على google و البدأ باستخدامها في تصميماتك و أخذ الالهام منها1 نقطة