-
المساهمات
143 -
تاريخ الانضمام
-
تاريخ آخر زيارة
إنجازات Ahmed Elmrsawy
-
مرحبا , ليس من الجيد بشكل عام تخزين الصور في قاعدة البيانات في شكل buffer و ذلك لأسباب تتعلق بالperformance و الScalability, ولكن بشكل عام فإذا كنت تستعمل node js فيمكنك فقط تخزين اسم التعريف لكل صورة مثلا تخزن اسم الصورة أنها image_1.png و عند الإستدعاء في الreact يقوم بوضع الurl الخاص بالbackend قبل التعريف مثلا : https://example.com/uploads/image_1.png ________ في حال ما إذا كنت تستعمل next js فأمر تخزين الصور يصبح أكثر تعقيدا خاصة في مراحل الproductions و في تلك الحالة يستحسن إستعمال aws مثال : للتخزين : const s3 = new S3Client({ region: "me-south-1", credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID as string, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string, }, }); //___________________________ import { PutObjectCommand } from "@aws-sdk/client-s3"; import generateUniqueId from "../date_id"; export default async function handleUploadFilesS3({ buffer, filename, }: { buffer: any; filename: string; }) { try { let newFileName = `${generateUniqueId()}_${filename.replaceAll( " ", "_" )}`; let command = new PutObjectCommand({ Bucket: process.env.AWS_S3_BUCKET_NAME as string, Key: newFileName, Body: buffer, }); await s3.send(command); return { name: newFileName, ok: true }; } catch (error) { console.log(error); return { error: error, ok: false }; } } للإسترجاع : const games = await prisma.game.findMany(); games.forEach(async (game) => { try { let command = new GetObjectCommand({ Bucket: process.env.AWS_S3_BUCKET_NAME, Key: game.gameImg as string, }); const url = await getSignedUrl(s3, command, { expiresIn: 3600 * 24 }); game.gameImg = url; } catch (err) { console.log(err); } }); ______ كمان يمكنك إستعمال طريقة الaws في المشاريع الخاصة بالnodejs أيضا .
-
مرحبا عند رفع الصور يتم استعمال الكود التالي : const s3 = new S3Client({ region: "me-south-1", credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID as string, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string, }, }); //___________________________ import { PutObjectCommand } from "@aws-sdk/client-s3"; import generateUniqueId from "../date_id"; export default async function handleUploadFilesS3({ buffer, filename, }: { buffer: any; filename: string; }) { try { let newFileName = `${generateUniqueId()}_${filename.replaceAll( " ", "_" )}`; let command = new PutObjectCommand({ Bucket: process.env.AWS_S3_BUCKET_NAME as string, Key: newFileName, Body: buffer, }); await s3.send(command); return { name: newFileName, ok: true }; } catch (error) { console.log(error); return { error: error, ok: false }; } } handleUploadFilesS3 هي دالة تأخذ بعض الarguments الخاصة بال file مثل الbuffer الخاص به و اسم الfile و تقوم بعمل id مميز له ثم رفعة _______________________________ لإسترجاع url لكل image (signed url) و هو يكون url مؤقت و ليس دائم و يمكنك التحكم في مدتة يتم تخزين في الداتابيز اسم الصورة فقط و ليس الurl لان الurl يكون مؤقت و يتم استعمال اسم الصورة لإنشاء الsigned url كالتالي : const games = await prisma.game.findMany(); games.forEach(async (game) => { try { let command = new GetObjectCommand({ Bucket: process.env.AWS_S3_BUCKET_NAME, Key: game.gameImg as string, }); const url = await getSignedUrl(s3, command, { expiresIn: 3600 * 24 }); game.gameImg = url; } catch (err) { console.log(err); } });
-
مرحبا , next هو إطار backend بالفعل و بإمكانك إستعمالة لبناء apis خاصة بك . إذا لماذا نستعمل express في حين أنة يمكننا استعمال Next دائما ؟ الإجابة أن express هو إطار عمل أخف ما يمكن أو كما يطلقون علية minimalist حيث أنة يكون أخف ما يمكن . على عكس الnext الذي إذا احتجتة لعمل مشروع apis فستجد أنك قمت بتحميل العديد من مزايا الnext الذي لن تحتاج إليها . كذلك الأمر أيضا في حال nest مع الأخذ في عين الإعتبار أن حجم nest اكبر من express . فمثلا إذا كان عليك إنشاء apis لتطبيق هاتف صغير نسبيا , ف في تلك الحالة هل هو أفضل إستعمال next او express أو nest ? في تلك الحالة فإنك لا تحتاج إلى خواص الSSR و ال file based routing و الSSG و غيرها فلا داعي لإستعمال next و وضعهم في مشروعك . في تلك الحالة نظرا لأن التطبيق نسبيا صغير فيفضل إستعمال express . و إذا كان التطبيق نسبيا كبير ف يفضل إستعمال nest . و إذا كنت على صدد إنشاء موقع أو تطبيق إلكتروني و تحتاج فيه إلى خواص الSSG و الSSR و الfile based routing ففي تلك الحالة يفضل إستعمال next. و هكذا , فإن معرفة واحدة منهم لا تغني عن الأخرين بلأن معرفتهم جميعا هو بالشئ الجيد و يكون القرار في النهاية على حسب متطلبات المشروع نفسة .
- 2 اجابة
-
- 1
-
و عليكم السلام . نعم , في أغلب الحالات فأنة يستحسن العمل في مشاريع الpython في بيئة افتراضية . و ذلك ليكون كل مشروع مستقل و معزول عن الباقي و الحزم الذي يحتاجها المشروع تكون مخصصة له فقط . و ذلك يكون إتباعا لمبدأ برمجي شهير يدعى Dependency Isolation . كما أنة أيضا في حالة أن كل مشروع له بيئة معزولة فإن ذلك يسهل من عملية الdeployment .
- 3 اجابة
-
- 1
-
مرحبا , هذة الفكرة جيدة جدا و في غاية الضرورة خاصة في المواقع الكبيرة نسبيا . و هذة الفكرة تطبق تلقائيا في مواقع الwordpress على سبيل المثال فإذا غيرت اللوجو أو اسم الوقع سيتم التغيير تلقائيا في الheader و إذا تريد جعل بيانات أخرى بشكل ديناميكي ف يمكنك عملها باستهدام دوال مثل get_option و غيرها و عامة في أي موقع مبني بأي لغة برمجة ف من المستخسن عمل لوحة تحكم للموقع و إتاحة للإمكانة للأدمن بتغيير الالبيانات . حيث يتم تخزين بيانات الموقع في جدول خاص بها في قاعدة البيانات , على سبيل المثال جدول site_data و يتم الإتاحة للأدمنز فقط بالتعديل عليها . و لا يوجد طريقة واحدة و ثابتة لتنفيذ العملية , أو حتا طريقة أو نهج واحد لكيفية التخزين ولكن في كل الأحوال فهذا الأمر ضروري للغاية و يجب وضعة في عين الإعتبار منذ البداية .
-
مرحبا , بالتأكيد ليس من الضروري تعلم الfront-end قبل الbackend متمثلة في لغة php . ولا من الضروري تعلم الfront-end حتا بعد تعلم الphp . بالتأكيد من المستحسن أن يكون لديك فكرة ولو بسيطة عن الfront-end و أيضا فهم لكيفية عمل الإنترنت بشكل عام . تلك المقالة لمساعدتك على أخذ فكرة أولية عن php و من هنا تستطيع الإنضمام للدورة . https://academy.hsoub.com/learn/php-web-application-development/
- 6 اجابة
-
- 1
-
مرحبا , في حال تطوير برنامج ديسك توب فلا يوجد خوف من تلك النقطة لأن البيانات تكون مخزنة في كل جهاز على حدى و ليس على سيرفر . و من أشهر قواعد البيانات المستخدمة في ذلك السياق هي قاعدة بيانات sqLite و هي شائعة الإستعمال في تطبيقات الديسكتوب و تطبيقات الهاتف أيضا . ___ في حال ما إذا كانت البيانات يتم تسجيلها على سيرفر و لا يريد المطور أن يكون وصول لتلك البيانات فمن الممكن تسجيل البيانات encrypted او hashed و يكون المفتاح الخاص لأسترجاع البيانات مع صاحب المشروع .
- 3 اجابة
-
- 1
-
مرحبا , برجاء إعطاء تفاصيل أكثر عن المشروع . و أيضا من المحبذ عمل التعليق في خانة التعليقات تحت الفيديو الخاص بالشرح مباشرة لأن ذلك سيعطي تفاصيل أكثر و سيتم التجاوب بشكل أسرع .
-
مرحبا , كما تم الشرح فإن الspread operator هو لعمل نسخة سطحية او shallow copy لدالة ما . و Array.push يقوم بتعديل العنصر نفسة و ليس نسخة . بالنسبة لأمر متى نستخدم كليهما : من المتعارف عليه أن تعديل array ما في بعض الأحيان و خاصة باستخدام الأمرين push و shift و unshift و pop , هذة الأمور تستهلك مجهودا من الcpu أكبر نسبيا من االمجهود الذي سوف يتم استخدامة إذا قمت بعمل نسخة . فمعرفة متى تستخدم كليهما تتوقف على أكثر من عامل ف مثلا إذا كنت تتعامل مع state في redux على سببيل المثال ف في هذة الحالة من المستحب استعمال spread operator و في العموم إذا كنت تتعامل مع array صغيرة نسبيا لن يشكل فارق كبير . تحياتي .
-
مرحبا , لاحظ في تلك الصورة أن الأمر ذهب إلى => /posts/undefined و ذلك معناه أن postId في دالة الreact بالتحديد هنا غير معرف من الممكن أن يكون معرفا خارج الدالة ولكنه ليس معرفا بداخلها تأكد من أنة معرف بداخل الدالة و قم بإرسال الأمر علية . تحياتي .
-
السلام عليكم , لإستعمال الواتساب و إرسال الرسائل يمكنك إما إستعمالة ك api كما قام المهندس محمد حسن بالوصف و من الممكن أيضا إستعمال bot يعمل حيث تكون فكرة عملة أنة يقوم بفتح متصفح جديد و يقوم بالدخول إلى حساب الواتاب الخاص بك و إستعمالة للإرسال و ذلك بالتأكيد بعد التوثيق . و من أشهر المكاتب المستهدمة في تطبيق ذلك مع node js هي مكتبة whatsapp-web.js وأنصحك بالبحث و إلقاء نظرة عليها . تحياتي .
- 6 اجابة
-
- 1
-
يوجد خطأ في طريقة عرض البيانات : حيث أنه لا داعي لإستعمال <php حاول أستخدام هذة الطريقة أفضل . <?php if ($result->num_rows > 0) { while ($row = $result->fetch_assoc()) { echo " <tr> <td>" . $row['تم'] . "</td> <td>" . $row['الحلول'] . "</td> <td>" . $row['المشكلة'] . "</td> <td>" . $row['م'] . "</td> <td>" . $row['الرقم'] . "</td> </tr>"; } } else { echo "<tr><td colspan='5'>لا توجد نتائج</td></tr>"; } // إغلاق الاتصال بقاعدة البيانات $conn->close(); ?>
- 2 اجابة
-
- 2
-
يوجد العديد من الطرق لتنفيذ المطلوب مثل عمل long-lasting http requests أو استعمال fireBase ولكن أشهرها هو استعمال الwebsockets, و يوجد مكتبات عديدة على حسب الframework المستعمل حيث يكون تحديد المستخدمين في الموقع الذين يستمعون على قناة معينة و عند حدوث أمر (event) يتم ابلاغهم . مثال : <?php namespace MyApp; use Ratchet\MessageComponentInterface; use Ratchet\ConnectionInterface; class NotificationHandler implements MessageComponentInterface { protected $clients; public function __construct() { $this->clients = new \SplObjectStorage; } public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); echo "New connection! ({$conn->resourceId})\n"; } public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); echo "Connection closed! ({$conn->resourceId})\n"; } public function onError(ConnectionInterface $conn, \Exception $e) { echo "An error occurred: {$e->getMessage()}\n"; $conn->close(); } public function onMessage(ConnectionInterface $from, $msg) { // عند تلقي رسالة، أرسلها إلى جميع العملاء الآخرين foreach ($this->clients as $client) { if ($client !== $from) { $client->send($msg); } } } } ?>
-
السلام عليكم , يمكنك تنفيذ المطلوب بأكثر من طريقة , على سبيل المثال اذا كنت تستعمل قاعدة بيانات mySql فيمكنك اما عمل جدول مخصص لعدد محاولات الuser الفاشلة و الربط بينة و بين جدول الuser عبر الid و في كل مرة يحاول فيها المستخدم التسجيل يتم فحص عدد المحاولات أولا . هناك طريقة أخرى و على سبيل المثال إذا كنت تستعمل mongoDb فيمكنك اضافة في الschema الخاصة بالuser عدد المحاولات الفاشلة و في حالة ان عدد المحاولات تجاوز ال5 يتم أيضا اضافة تاريخ فك الحظر الذي تريدة . و عند تسجيل الدخول يتم التأكد أولا , اذا كان تاريخ فك الحظر لم يأتي بعد ف يتم ارسال خطأ مثال : const express = require('express'); const mongoose = require('mongoose'); const bcrypt = require('bcrypt'); const rateLimit = require('express-rate-limit'); const app = express(); const PORT = 3000; // Connect to MongoDB mongoose.connect('mongodb://localhost:27017/yourDatabase', { useNewUrlParser: true, useUnifiedTopology: true }); // Define User Schema const userSchema = new mongoose.Schema({ username: String, password: String, loginAttempts: { type: Number, default: 0 }, lockUntil: { type: Number, default: 0 }, }); const User = mongoose.model('User', userSchema); // Rate Limit Middleware const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 5, // limit each IP to 5 requests per windowMs message: 'Too many login attempts. Try again later.', }); app.use('/login', limiter); // Login Endpoint app.post('/login', async (req, res) => { const { username, password } = req.body; // Check if the account is locked const user = await User.findOne({ username }); if (user && user.lockUntil > Date.now()) { return res.status(429).send('Account is locked. Try again later.'); } // Check the password const passwordMatch = await bcrypt.compare(password, user.password); if (passwordMatch) { // Reset login attempts upon successful login await User.findOneAndUpdate({ username }, { loginAttempts: 0, lockUntil: 0 }); res.send('Login successful!'); } else { // Increase login attempts and lock the account if necessary await User.findOneAndUpdate({ username }, { $inc: { loginAttempts: 1 }, $set: { lockUntil: getLockExpirationTime() } }); res.status(401).send('Invalid username or password.'); } }); // Helper function to calculate lock expiration time function getLockExpirationTime() { return Date.now() + 15 * 60 * 1000; // Lock for 15 minutes } app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); }); ________ بالنسبة للfrontend و react فالتعامل معه في هذة الحالة هو نفس التعامل مع api بشكل عادي
- 2 اجابة
-
- 1