در این سوال از شما میخواهیم که بخشی از کوئرا فریمورک را طراحی کنید.
توضیحات
- در این فریمورک برای ورود و احراز هویت کاربر از
JWT(Json Web Token)استفاده می شود. - همچنین برای ذخیرهسازی اطلاعات کاربران از
sqlite3استفاده میشود. - سعی شده در این پروژه برای تمامی توابع توضیحات مناسب بر روی کد قرار داده شدهباشد.
- دقت کنید سعی شده هر بخش به شکل جدا نمرهدهی شود و با پیادهسازی قسمتی از سوال، بتوانید نمرهی آن قسمت را دریافت کنید ( بجز بخشهایی که با یکدیگر ارتباط نزدیک دارند مانند
signUpوsignIn) . - در تمامی بخشهای کار با فایل برای رفتن به خط جدید از
\nاستفاده کنید. - پروژهی اولیه در زیر قرار گرفتهاست، لازم است قسمتهایی که کامنت
TODO: implementدارند را پیادهسازی کنید.
پایگاه داده
برای شروع پایگاه دادهای با نام qdb.sqlite در جایی که bootstrap.php در آن قرار دارد، ایجاد کنید.
در این پایگاه داده باید یک جدول به نام users وجود داشتهباشد که ستونهای آن به شرح زیر است:
id:INTEGER PRIMARY KEY NOT NULLname:TEXT NOT NULLpassWD:TEXT NOT NULLfirstName:TEXT NOT NULLlastName:TEXT NOT NULLemail:TEXT NOT NULL
بخشهایی که باید آنها را تکمیل کنید
bootstrap.php
autoload
این تابع به عنوان تابع ورودی به spl_autoload_register داده خواهد شد.
این تابع باید در صورت ایجاد شدن شیء از هر یک کلاسهای موجود در پوشهی برنامه، که ساختار نامگذاری فایل آنها بصورت class.نام کلاس.php می باشد، فایل مربوط را require_once کند.
quera_exception_handler
این تابع باید exceptionٰهای دریافتی خود را در پوشه برنامه و در فایل exception.log ذخیره کند.
به ازای هر exception باید توضیحات آن را با فرمت زیر در خط جدیدی به فایل اضافه نمایید.
این تابع به عنوان ورودی به set_exception_handler داده خواهد شد.
$file - $line : $message
برای مثال یکی از خطوط ذخیره شده در فایل می تواند به این صورت باشد :
/project/test.php - 12 : Some error message
quera_error_handler
این تابع باید errorهای دریافتی خود را در پوشه برنامه و در فایل error.log ذخیره کند.
به ازای هر error باید توضیحات آن را با فرمت زیر در خط جدیدی به فایل اضافه نمایید.
این تابع به عنوان ورودی به set_error_handler داده خواهد شد.
$level - $filename - $line : $message
برای مثال یکی از خطوط ذخیره شده در فایل میتواند به این صورت باشد:
E_USER_NOTICE - /project/test.php - 18 : Value at position 2 is not a number, using 0 (zero)
- برای ذخیره
exceptionوerrorالزامی برای استفاده از کلاسLogنیست. - بهتر است برای دسترسی به آدرس پوشه برنامه از
QUERA_FRAMEWORK_ROOTاستفاده کنید.
class.log.php
__construct
تنها ورودی آن ، آدرس فایل مورد نظر جهت ذخیره لاگ میباشد. در صورت عدم وجود آن فایل ، آن را ایجاد میکند.
writeLog
دو ورودی message و alertDetail میگیرد و در انتهای فایل مورد نظر در خط جدید بصورت زیر مینویسد. در صورتی که فایل خالی بود از ابتدا فایل شروع میکند.
$alertDetail : $message
class.router.php
در این کلاس پنج تابع post, get, put, delete, resolve را به نحوی پیادهسازی کنید که عملیاتهای زیر را انجام دهند.
هر یک از توابع post, get, put, delete سه ورودی میگیرند که به ترتیب زیر میباشند :
- آدرس ورودی جهت مسیریابی
- آرایهای با دو عضو که عضو اول آن یک شیء از یک کلاس و عضو دوم آن نام تابعی از آن کلاس است.
- آرایهای از آرگومانهایی که برای اجرای تابع مشخص شده از آنها استفاده میشود (می تواند آرایهای خالی باشد)
- در ورودی این توابع می توان از
[s]یا[i]استفاده کرد که به ترتیب نشاندهندهی یکstringوintegerهستند. - برای مثال اگر url ورودی تابع
/api/[i]/باشد میتواند هرکدام از مسیر های/api/21312/یا/api/3123/یا/api/1/?test=sampleرا مسیریابی کند.
تابع resolve نیز دو ورودی میگیرد که به ترتیب زیر میباشند:
- متدی که برنامه با آن فراخوانی شده است ( برای مثال :
GET) - آدرس ورودی جهت مسیریابی
- تابع
resolveدر صورت یافتن مسیر مناسب تابع مورد نظر آن مسیریابی را با آرگومان های مشخص شده اجرا می کند وtrueبر میگرداند و در صورت عدم یافتن مسیریابی مناسبfalseبر میگرداند. - اگر چند مسیریابی برای یک مسیرقابل قبول بودند الویت با مسیری است که زودتر از بقیه افزوده شده باشد.
[s]می تواند هر کاراکتری بجز/را شامل شود.
برای مثال یک استفاده از Router میتواند به صورت زیر باشد:
$app = new Router();
$app->post('/api/v1/Message/', array(new Controller(),'sendMessage'), array());
$app->get('/api/v1/User/[s]/', array(new Controller(),'getUser'), array());
$app->resolve($_SERVER['REQUEST_METHOD'],$_SERVER['REQUEST_URI']);
class.controller.php
signUp
اطلاعات ورودی ثبت نام یک کاربر را گرفته و در پایگاه داده ذخیره میکند. ورودیهای تابع به صورت زیر میباشند.
- نام کاربری
- رمز عبور
- نام
- نام خانوادگی
- ایمیل
- تمامی اطلاعات کاربر بجز رمز عبور را همانگونه که به تابع داده می شود در پایگاه داده ذخیره کنید.
- رمز عبور را نیز با استفاده از
native password hashing APIموجود درPHPو با استفاده از الگوریتمPASSWORD_BCRYPTرمزگذاری کرده و سپس در پایگاه داده ذخیره کنید.
checkSignIn
یک نام کاربری و یک رمزعبور (بصورت رمزگذاری نشده) را به عنوان ورودی میگیرد و از پایگاه داده بررسی میکند که آیا اطلاعات ورودی صحیح است یا خیر.
createToken
این تابع SECRET, HEADER, PAYLOAD را دریافت کرده و به عنوان خروجی JWT را برمیگرداند.
- الگوریتم مورد نظر جهت رمزنگاری
HS256میباشد. - نیاز به
secret base64 encodedنیست. - دقت کنید که باید تمام
TOKENرا با فرمت صحیح برگردانید و برگرداندنSIGNATUREبه تنهایی کافی نیست.
checkToken
این تابع SECRET, TOKEN دریافت می کند و تایید میکند که آیا این TOKEN با استفاده از این SECRET مورد تایید است یا خیر.
بارگذاری
فایلهای class.controller.php، class.log.php، class.router.php، qdb.sqlite و bootstrap.php را داخل یک فایل زیپ قرار داده و بارگذاری کنید.
ارسال پاسخ برای این سؤال