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

Ahmed Elmrsawy

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

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

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

1 متابع

آخر الزوار

لوحة آخر الزوار معطلة ولن تظهر للأعضاء

إنجازات Ahmed Elmrsawy

عضو نشيط

عضو نشيط (3/3)

46

السمعة بالموقع

2

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

  1. مرحبا , 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. و عليكم السلام . نعم , في أغلب الحالات فأنة يستحسن العمل في مشاريع الpython في بيئة افتراضية . و ذلك ليكون كل مشروع مستقل و معزول عن الباقي و الحزم الذي يحتاجها المشروع تكون مخصصة له فقط . و ذلك يكون إتباعا لمبدأ برمجي شهير يدعى Dependency Isolation . كما أنة أيضا في حالة أن كل مشروع له بيئة معزولة فإن ذلك يسهل من عملية الdeployment .
  3. مرحبا , هذة الفكرة جيدة جدا و في غاية الضرورة خاصة في المواقع الكبيرة نسبيا . و هذة الفكرة تطبق تلقائيا في مواقع الwordpress على سبيل المثال فإذا غيرت اللوجو أو اسم الوقع سيتم التغيير تلقائيا في الheader و إذا تريد جعل بيانات أخرى بشكل ديناميكي ف يمكنك عملها باستهدام دوال مثل get_option و غيرها و عامة في أي موقع مبني بأي لغة برمجة ف من المستخسن عمل لوحة تحكم للموقع و إتاحة للإمكانة للأدمن بتغيير الالبيانات . حيث يتم تخزين بيانات الموقع في جدول خاص بها في قاعدة البيانات , على سبيل المثال جدول site_data و يتم الإتاحة للأدمنز فقط بالتعديل عليها . و لا يوجد طريقة واحدة و ثابتة لتنفيذ العملية , أو حتا طريقة أو نهج واحد لكيفية التخزين ولكن في كل الأحوال فهذا الأمر ضروري للغاية و يجب وضعة في عين الإعتبار منذ البداية .
  4. مرحبا , بالتأكيد ليس من الضروري تعلم الfront-end قبل الbackend متمثلة في لغة php . ولا من الضروري تعلم الfront-end حتا بعد تعلم الphp . بالتأكيد من المستحسن أن يكون لديك فكرة ولو بسيطة عن الfront-end و أيضا فهم لكيفية عمل الإنترنت بشكل عام . تلك المقالة لمساعدتك على أخذ فكرة أولية عن php و من هنا تستطيع الإنضمام للدورة . https://academy.hsoub.com/learn/php-web-application-development/
  5. مرحبا , في حال تطوير برنامج ديسك توب فلا يوجد خوف من تلك النقطة لأن البيانات تكون مخزنة في كل جهاز على حدى و ليس على سيرفر . و من أشهر قواعد البيانات المستخدمة في ذلك السياق هي قاعدة بيانات sqLite و هي شائعة الإستعمال في تطبيقات الديسكتوب و تطبيقات الهاتف أيضا . ___ في حال ما إذا كانت البيانات يتم تسجيلها على سيرفر و لا يريد المطور أن يكون وصول لتلك البيانات فمن الممكن تسجيل البيانات encrypted او hashed و يكون المفتاح الخاص لأسترجاع البيانات مع صاحب المشروع .
  6. مرحبا , برجاء إعطاء تفاصيل أكثر عن المشروع . و أيضا من المحبذ عمل التعليق في خانة التعليقات تحت الفيديو الخاص بالشرح مباشرة لأن ذلك سيعطي تفاصيل أكثر و سيتم التجاوب بشكل أسرع .
  7. مرحبا , كما تم الشرح فإن الspread operator هو لعمل نسخة سطحية او shallow copy لدالة ما . و Array.push يقوم بتعديل العنصر نفسة و ليس نسخة . بالنسبة لأمر متى نستخدم كليهما : من المتعارف عليه أن تعديل array ما في بعض الأحيان و خاصة باستخدام الأمرين push و shift و unshift و pop , هذة الأمور تستهلك مجهودا من الcpu أكبر نسبيا من االمجهود الذي سوف يتم استخدامة إذا قمت بعمل نسخة . فمعرفة متى تستخدم كليهما تتوقف على أكثر من عامل ف مثلا إذا كنت تتعامل مع state في redux على سببيل المثال ف في هذة الحالة من المستحب استعمال spread operator و في العموم إذا كنت تتعامل مع array صغيرة نسبيا لن يشكل فارق كبير . تحياتي .
  8. مرحبا , لاحظ في تلك الصورة أن الأمر ذهب إلى => /posts/undefined و ذلك معناه أن postId في دالة الreact بالتحديد هنا غير معرف من الممكن أن يكون معرفا خارج الدالة ولكنه ليس معرفا بداخلها تأكد من أنة معرف بداخل الدالة و قم بإرسال الأمر علية . تحياتي .
  9. السلام عليكم , لإستعمال الواتساب و إرسال الرسائل يمكنك إما إستعمالة ك api كما قام المهندس محمد حسن بالوصف و من الممكن أيضا إستعمال bot يعمل حيث تكون فكرة عملة أنة يقوم بفتح متصفح جديد و يقوم بالدخول إلى حساب الواتاب الخاص بك و إستعمالة للإرسال و ذلك بالتأكيد بعد التوثيق . و من أشهر المكاتب المستهدمة في تطبيق ذلك مع node js هي مكتبة whatsapp-web.js وأنصحك بالبحث و إلقاء نظرة عليها . تحياتي .
  10. يوجد خطأ في طريقة عرض البيانات : حيث أنه لا داعي لإستعمال <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(); ?>
  11. يوجد العديد من الطرق لتنفيذ المطلوب مثل عمل 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); } } } } ?>
  12. السلام عليكم , يمكنك تنفيذ المطلوب بأكثر من طريقة , على سبيل المثال اذا كنت تستعمل قاعدة بيانات 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 بشكل عادي
  13. السلام عليكم , يمكنك محاولة ضبطها باستخدام رمز e الذي يرمز الى الشرق و هو ما يعادل اليمين , كما في المثال التالي import CTkFrame app = CTkFrame.CTk() label = CTkFrame.Label(app, text="نص التسمية") label.grid(row=0, column=0, sticky="e") # تعيين sticky="e" لتحديد اليمين app.run()
  14. قم باستعمال الأمر dir و سيعرض لك قائمة بالملفات و المجلدات الموجودة في مكانك التي يمكنك الانتقال اليها اذا كان هناك desktop فقم بالانتقال اليها و اذا لم تكن موجودة فلا تسطيع الانتقال اليها من ذلك الuser و على الأغلب ستجدها في user أخر .
  15. مرحبا , الكود الذي قدمته يحتوي على بعض الأخطاء. سأقوم بتصحيحها وشرح التعديلات: في كود الـ PHP الرئيسي: يجب تغيير echo $stroecustomer; إلى echo $storecustomer; حيث أنك قمت بتخزين نتيجة الدالة في $storecustomer وليس $stroecustomer. أنت تستخدم دالة stroecustomer بدلاً من storecustomer، قم بتصحيح ذلك. تعديل الأمر if (empty($inputData)) إلى if (empty($inputData)) { لإغلاق الفاصلة العلوية. في ملف الدوال: في استعمال الـ SQL في دالة stroecustomer يجب أن تتأكد من أن أسماء الأعمدة معرفة بشكل صحيح. في حالتك، يبدو أن هناك خطأ في الاسماء. يجب تغيير 'INSERT INTO users (name,email.phone) VALUES ('$name','$email','$phone') " إلى 'INSERT INTO users (name,email,phone) VALUES ('$name','$email','$phone') ". يمكنك التحقق من رسائل الخطأ في MySQL عند القيام بأي استعلام باستخدام mysqli_error($conn) للتحقق من الأخطاء. لتحسين أمان قاعدة البيانات، يمكنك استخدام prepared statements بدلاً من تركيب القيم مباشرة في الاستعلام. يفضل تحديد أسماء الأعمدة المراد استرجاعها في SELECT * بشكل صريح بدلاً من استخدام SELECT *. بعد تحديث الكود، ينبغي أن يكون لديك شيء مشابه للكود التالي: <?php error_reporting(0); header('Access-Control-Allow-Origin: *'); header('Content-Type: application/json'); header('Access-Control-Allow-Method: POST'); header('Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, x-requested-with '); include('function.php'); $requestMethod = $_SERVER["REQUEST_METHOD"]; if ($requestMethod == "POST") { $inputData = json_decode(file_get_contents("php://input"), true); if (empty($inputData)) { $storecustomer = storecustomer($_POST); } else { $storecustomer = storecustomer($inputData); } echo $storecustomer; } else { $data = [ 'status' => 405, 'message' => $requestMethod.' Method Not Allowed', ]; header("HTTP/1.0 405 Method Not Allowed"); echo json_encode($data); } ?> وفي ملف الدوال: <?php require '../inc/dbcon.php'; function error422($message) { $data = [ 'status' => 422, 'message' => $message, ]; header("HTTP/1.0 422 Unprocessable Entity"); echo json_encode($data); exit(); } function storecustomer($customerinput) { global $conn; $name = mysqli_real_escape_string($conn, $customerinput['name']); $email = mysqli_real_escape_string($conn, $customerinput['email']); $phone = mysqli_real_escape_string($conn, $customerinput['phone']); if (empty(trim($name)) || empty(trim($email)) || empty(trim($phone))) { return error422('Please enter valid data for all fields.'); } $query = "INSERT INTO users (name,email,phone) VALUES ('$name','$email','$phone') "; $result = mysqli_query($conn, $query); if ($result) { $data = [ 'status' => 201, 'message' => 'User Created Successfully', ]; header("HTTP/1.0 201 Created"); return json_encode($data); } else { $data = [ 'status' => 500, 'message' => 'Internal Server Error: ' . mysqli_error($conn), ]; header("HTTP/1.0 500 Internal Server Error"); return json_encode($data); } } function getcustomerlist() { global $conn; $query = "SELECT * FROM users"; $query_run = mysqli_query($conn, $query); if ($query_run) { if (mysqli_num_rows($query_run) > 0) { $res = mysqli_fetch_all($query_run, MYSQLI_ASSOC); $data = [ 'status' => 200, 'message' => 'User list Fetched Successfully ', 'data' => $res, ]; header("HTTP/1.0 200 OK"); return json_encode($data); } else { $data = [ 'status' => 404, 'message' => 'No User Found ', ]; header("HTTP/1.0 404 No User Found"); return json_encode($data); } } else { $data = [ 'status' => 500, 'message' => 'Internal Server Error: ' . mysqli_error($conn), ]; header("HTTP/1.0 500 Internal Server Error"); return json_encode($data); } } ?>
×
×
  • أضف...