معین پس از مدتها حضور در **کوئرا،** تصمیم گرفت برای ایجاد تنوع، در مصاحبه استخدامی **جونیورا** شرکت کند؛ در این مصاحبه از او خواستهاند که پروژهای با استفاده از [_ORM_](https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping) مخصوص _Laravel_ انجام دهد؛ اما او معتقد است *هرکسی میتواند با کمی آموزش، رانندگی را یاد بگیرد؛ ولی فقط یک مکانیک دقیقاً میداند ماشین چگونه کار میکند.* بنابراین، تصمیم گرفت با هدف نشاندادن تبحر واقعی خود، بهجای استفاده از _ORM_ آماده، **یک _ORM_ اختصاصی به زبان _PHP_ بنویسد** و آن را به افتخار خودش **معین سخنور (_Moein Eloquent_)** نامگذاری کند. مشکل اینجاست که پروژه اصلی بهاندازه کافی وقتگیر است و معین برای پیادهسازی _ORM_ اختصاصیاش به زمان بیشتری نیاز دارد؛ از همین رو، او از شما کمک میخواهد تا در تکمیل این _ORM_ همراهش باشید.

# جزئیات پروژه
پروژه اولیه را از [این لینک](/contest/assignments/81560/download_problem_initial_project/279970/) دانلود کنید.
<details class="yellow">
<summary>**ساختار فایلها**</summary>
```
moein-eloquent
├── Database.php
├── <mark class="orange" title="این فایل باید پیادهسازی شود">> QueryBuilder.php <</mark>
├── <mark class="orange" title="این فایل باید پیادهسازی شود">> Model.php <</mark>
├── User.php
├── autoload.php
└── test
└── EloquentSampleTest.php
```
</details>
<details class="grey">
<summary>**راهاندازی پروژه**</summary>
برای راهاندازی پروژه، به پایگاهداده _MySQL_ نیاز است. در این بخش، به راهاندازی _MySQL_ در داکر میپردازیم. اگر تاکنون داکر را نصب نکردهاید، بهکمک [این لینک](https://www.docker.com/get-started/) آن را نصب کنید.
برای نصب و راهاندازی کانتینر _MySQL_ بهکمک داکر، دستور زیر را در ترمینال وارد کنید تا ایمیج _MySQL_ دانلود شود و کانتینر راهاندازی شود:
``` bash terminal terminal
docker run --name mysql-container \
-e MYSQL_ALLOW_EMPTY_PASSWORD=yes \
-e MYSQL_DATABASE=testdb \
-p 3306:3306 \
-d mysql:latest
```
وقتی مراحل نصب کامل شد، دستور زیر را در ترمینال وارد کنید تا با سرویس _MySQL_ در کانتینر ساختهشده ارتباط برقرار کنید:
``` bash terminal terminal
docker exec -it mysql-container mysql -u root
```
حال دستور زیر را در محیط تعاملی _MySQL_ وارد کنید تا پایگاهداده `testdb` استفاده شود:
``` sql sql sql
USE testdb;
```
اکنون میتوانیم جدول `users` را ایجاد کنیم؛ دستور زیر را وارد کنید تا جدول `users` در پایگاهداده `testdb` ساخته شود:
``` sql sql sql
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
age INT NOT NULL
);
```
</details>
این پروژه **شامل ۵ فایل است که ۳ فایل از قبل تکمیل شدهاند**. شما باید فایلهای `Model.php` و `QueryBuilder.php` را پیادهسازی کنید؛ در ادامه، جزئیات هرکدام از فایلها و متدهای آنها را میتوانید مشاهده کنید:
<details class="blue">
<summary>**فایل** `Database.php`</summary>
این فایل شامل یک کلاس بهنام `Database` است که یک شی `pdo` را مقداردهی اولیه میکند و میتوان با استفاده از `Database::getInstance()` به آن دسترسی پیدا کرد. **این فایل از قبل پیادهسازی شده و شما نیازی به تغییر در آن ندارید**؛ در پروژه ارسالی شما، این فایل جایگزین میشود، بنابراین هر تغییری در آن ایجاد کنید، نادیده گرفته خواهد شد. اما اگر میخواهید نتایج کوئریهایتان ببینید، باید مقادیر موجود در این فایل را تغییر دهید تا بتوانید پروژه را روی سیستم خودتان اجرا کنید.
``` php Database.php php
<?php
class Database {
private static $instance = null;
private $pdo;
private function __construct() {
$this->pdo = new PDO("mysql:host=127.0.0.1;dbname=testdb", "root", "");
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new Database();
}
return self::$instance->pdo;
}
}
?>
```
</details>
<details class="red">
<summary>**فایل** `QueryBuilder.php`</summary>
کلاس `QueryBuilder` برای **ساخت و اجرای کوئریهای پایگاهداده** طراحی شده است. این کلاس امکاناتی مانند `SELECT`، `WHERE`، `GROUP BY`، `HAVING`، `ORDER BY`، `LIMIT` و عملیات [**CRUD**](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) را فراهم میکند. در پیادهسازی متدهای این کلاس، از [**دیزاین پترن Builder**](https://refactoring.guru/design-patterns/builder) استفاده کنید.
<details class="yellow">
<summary>متد `select()`</summary>
این متد تعیین میکند که **کدام ستونها** در نتایج `SELECT` آورده شوند.
``` php
public function select(...$columns): self
{
// TODO
}
```
### مثال
``` php
User::select('name', 'age')->get();
User::select(['name', 'age'])->get();
User::select('*')->get();
User::select('age', 'COUNT(*) AS count')->groupBy('age')->get();
```
</details>
<details class="yellow">
<summary>متد `where()`</summary>
این متد برای **افزودن شرطها به کوئریهای `WHERE`** استفاده میشود.
- امکان استفاده از عملگرهای مقایسهای (`=`, `>`, `<`, `LIKE`، و ...) وجود دارد.
- در صورتی که فقط دو آرگومان به متد داده شود، عملگر مقایسهای پیشفرض (`=`) در نظر گرفته میشود.
``` php
public function where(string $column, mixed $operator = null, mixed $value = null): self
{
// TODO
}
```
### مثال
``` php
User::where('age', '>=', '32')->get();
User::where('age', '=', '40')->get();
User::where('age', '22')->get();
User::where('name', 'LIKE', 'M%')->get();
```
</details>
<details class="yellow">
<summary>متد `groupBy()`</summary>
این متد کوئری را براساس یک یا چند ستون گروهبندی (`GROUP BY`) میکند.
``` php
public function groupBy(...$columns): self
{
// TODO
}
```
### مثال
``` php
User::select('age', 'COUNT(*) AS count')->groupBy('age')->get();
User::select('age', 'email', 'COUNT(*) AS count')->groupBy('age', 'email')->get();
```
</details>
<details class="yellow">
<summary>متد `having()`</summary>
این متد برای فیلترکردن نتایج پس از `GROUP BY` استفاده میشود.
``` php
public function having(string $column, string $operator, mixed $value): self
{
// TODO
}
```
### مثال
``` php
User::select('age', 'COUNT(*) AS count')->groupBy('age')->having('age', '>', 32)->get();
```
</details>
<details class="yellow">
<summary>متد `orderBy()`</summary>
این متد **چیدمان نتایج** را براساس یک ستون و ترتیب `ASC` یا `DESC` تعیین میکند.
``` php
public function orderBy(string $column, string $direction = 'ASC'): self
{
// TODO
}
```
### مثال
``` php
User::orderBy('age')->get();
User::orderBy('age')->orderBy('name', 'DESC')->get();
```
</details>
<details class="yellow">
<summary>متد `limit()`</summary>
این متد تعداد نتایج بازگشتی را محدود (`LIMIT`) میکند.
``` php
public function limit(int $limit): self
{
// TODO
}
```
### مثال
``` php
User::orderBy('age')->limit(1)->get();
```
</details>
<details class="yellow">
<summary>متد `offset`</summary>
این متد تعدادی از نتایج بازگشتی را رد (_skip_) میکند.
``` php
public function offset(int $offset): self
{
// TODO
}
```
### مثال
``` php
User::orderBy('age')->offset(1)->limit(1)->get();
```
</details>
<details class="yellow">
<summary>متد `get()`</summary>
این متد کوئری نهایی را **اجرا** کرده و نتایج را **بهصورت آرایهای از اشیا مدل** برمیگرداند.
``` php
public function get(): array
{
// TODO
}
```
</details>
<details class="yellow">
<summary>متد `first()`</summary>
این متد **اولین نتیجهی** کوئری را دریافت کرده و مقدار `null` را در صورت خالیبودن بازمیگرداند.
``` php
public function first()
{
// TODO
}
```
### مثال
``` php
User::orderBy('age', 'DESC')->first();
```
</details>
<details class="yellow">
<summary>متد `count()`</summary>
این متد تعداد کل ردیفهای خروجی کوئری را برمیگرداند (`COUNT(*)`).
``` php
public function count(): int
{
// TODO
}
```
### مثال
``` php
User::count();
User::where('age', 24)->count()
```
</details>
<details class="yellow">
<summary>متدهای `sum()`, `avg()`, `min()`, `max()`</summary>
این متدها مقدار **مجموع**، **میانگین**، **حداقل** و **حداکثر** یک ستون را محاسبه میکنند.
``` php
private function aggregate($function, $column)
{
// TODO
}
public function sum($column)
{
// TODO
}
public function avg($column)
{
// TODO
}
public function min($column)
{
// TODO
}
public function max($column)
{
// TODO
}
```
### مثال
``` php
User::sum('age');
User::avg('age');
User::min('age');
User::max('age');
```
</details>
<details class="yellow">
<summary>متد `insert()`</summary>
این متد یک **رکورد جدید** در پایگاهداده درج (`INSERT`) کرده و `id` آن را برمیگرداند.
``` php
public function insert(array $data): int
{
// TODO
}
```
### مثال
``` php
User::insert(
[
'id' => 10,
'name' => 'New User',
'age' => 50,
'email' => 'newuser@email.com'
]
)
```
</details>
<details class="yellow">
<summary>متد `update()`</summary>
این متد دادههای جدول را بر اساس `WHERE` **بهروزرسانی** میکند.
- اگر شرط `WHERE` تعیین نشده باشد، خطا (`Exception`) ایجاد میشود.
``` php
public function update(array $data): bool
{
// TODO
}
```
### مثال
``` php
User::where('id', 10)->update(['name' => 'Newer Name']);
```
</details>
<details class="yellow">
<summary>متد `delete()`</summary>
این متد رکوردهای پایگاهداده را حذف (`DELETE`) میکند.
- اگر `WHERE` تعیین نشده باشد، عملیات متوقف شده و خطا (`Exception`) صادر میشود.
``` php
public function delete(): bool
{
// TODO
}
```
### مثال
``` php
User::where('id', 10)->delete();
```
</details>
</details>
<details class="red">
<summary>**فایل** `Model.php`</summary>
این فایل باید پیادهسازی شود. در این فایل یک **کلاس انتزاعی (_abstract_)** بهنام `Model` وجود دارد که **مدلهای پایگاهداده از آن ارثبری میکنند**. این کلاس دو پراپرتی دارد؛ نام جدول و آرایه `attributes`. نام جدول باید توسط مدلهایی که از این کلاس ارثبری میکنند _Overwrite_ شود. آرایه `attributes` برای ستکردن پراپرتیهای _dynamic_ است. این کلاس دارای چند متد است که باید پیادهسازی شوند:
<details class="yellow">
<summary>متد `query()`</summary>
این متد یک **شیء از کلاس `QueryBuilder`** ایجاد کرده و برای اجرای کوئریهای پایگاهداده مورد استفاده قرار میگیرد.
``` php
public static function query(): QueryBuilder
{
// TODO
}
```
</details>
<details class="yellow">
<summary>متد `allQuery()`</summary>
این متد تمام رکوردهای موجود در جدول مرتبط با مدل را دریافت کرده و **بهصورت آرایهای از اشیا** برمیگرداند.
``` php
public static function allQuery(): array
{
// TODO
}
```
### مثال
``` php
User::all();
```
</details>
<details class="yellow">
<summary>متد `findQuery()`</summary>
این متد یک رکورد خاص را بر اساس مقدار `id` جستوجو میکند.
- اگر رکوردی یافت شود، **نمونهای از مدل** را برمیگرداند.
- در غیر این صورت مقدار `null` برمیگردد.
``` php
public static function findQuery(int $id): ?self
{
// TODO
}
```
### مثال
``` php
User::find(1);
```
</details>
<details class="yellow">
<summary>متد `createQuery()`</summary>
این متد یک رکورد جدید در جدول مرتبط با مدل ایجاد میکند.
- دادههای جدید را در پایگاهداده **درج** کرده و نمونهای از مدل را که شامل این دادهها است، برمیگرداند.
``` php
public static function createQuery(array $data): ?self
{
// TODO
}
```
### مثال
``` php
User::create([
'id' => 20,
'name' => 'Jason Voorhees',
'email' => 'jason@gmail.com',
'age' => 60
]);
```
</details>
<details class="yellow">
<summary>متد `firstQuery()`</summary>
این متد **اولین رکورد موجود** در جدول را دریافت کرده و بهعنوان نمونهای از مدل برمیگرداند.
``` php
public static function firstQuery(): ?self
{
// TODO
}
```
### مثال
``` php
User::first();
```
</details>
<details class="yellow">
<summary>متد `hydrateQuery()`</summary>
این متد یک نمونه از مدل را با دادههای ورودی مقداردهی میکند.
- برای **پر کردن شیء مدل از یک آرایه داده** استفاده میشود.
``` php
public static function hydrateQuery(array $data): self
{
// TODO
}
```
</details>
<details class="yellow">
<summary>متد `updateQuery()`</summary>
این متد مقدار فیلدهای یک رکورد را **بهروزرسانی** میکند.
- رکورد مورد نظر باید در _object_ و پایگاهداده همزمان بهروزرسانی شود.
- اگر بهروزرسانی موفقیتآمیز باشد، مقدار `true` برمیگردد.
- در غیر این صورت مقدار `false` بازمیگردد.
``` php
public function updateQuery(array $data): bool
{
// TODO
}
```
### مثال
``` php
$user = User::find(1);
$user->update(['age' => 30]);
```
</details>
<details class="yellow">
<summary>متد `deleteQuery()`</summary>
این متد رکورد مربوطه را از پایگاهداده **حذف** میکند.
- اگر حذف موفقیتآمیز باشد، مقدار `true` برمیگردد.
- در غیر این صورت مقدار `false` بازمیگردد.
``` php
public function deleteQuery(): bool
{
// TODO
}
```
### مثال
``` php
$user = User::find(1);
$user->delete();
```
</details>
</details>
<details class="blue">
<summary>**فایل** `User.php`</summary>
این فایل شامل یک کلاس `User` است که از کلاس `Model` ارثبری میکند. در این کلاس، صرفا مقادیر مورد نیاز تعریف یا مقداردهی شدهاند. شما نیازی به پیادهسازی این فایل ندارید.
``` php User.php php
<?php
require_once 'autoload.php';
class User extends Model {
protected static string $table = 'users';
public int $id;
public string $name;
public string $email;
public int $age;
}
?>
```
</details>
<details class="blue">
<summary>**فایل** `autoload.php`</summary>
این فایل صرفا شامل یک رجیستر است که کلاسهای مورد نیاز را از فایلهای دیگر فراخوانی میکند. شما نیازی به پیادهسازی این فایل ندارید.
``` php autoload.php php
<?php
spl_autoload_register(function ($class_name) {
require __DIR__ . "/$class_name.php";
});
?>
```
</details>
# نکات
- برای حل این سوال باید از [**دیزاین پترن Builder**](https://refactoring.guru/design-patterns/builder) استفاده کنید.
- دقت کنید که صرفا تغییراتی که در فایلهای `QueryBuilder.php` و `Model.php` ایجاد میکنید بررسی خواهند شد؛ **تغییراتی که در فایلهای دیگر پروژه ایجاد میکنید در سیستم داوری نادیده گرفته خواهند شد.**
# آنچه باید آپلود کنید
پس از پیادهسازی فایلهای مورد نیاز، فایلهای `QueryBuilder.php` و `Model.php` را بهصورت فایل _Zip_ ارسال کنید.
معین سخنور
معین پس از مدتها حضور در کوئرا، تصمیم گرفت برای ایجاد تنوع، در مصاحبه استخدامی جونیورا شرکت کند؛ در این مصاحبه از او خواستهاند که پروژهای با استفاده از ORM مخصوص Laravel انجام دهد؛ اما او معتقد است هرکسی میتواند با کمی آموزش، رانندگی را یاد بگیرد؛ ولی فقط یک مکانیک دقیقاً میداند ماشین چگونه کار میکند. بنابراین، تصمیم گرفت با هدف نشاندادن تبحر واقعی خود، بهجای استفاده از ORM آماده، یک ORM اختصاصی به زبان PHP بنویسد و آن را به افتخار خودش معین سخنور (Moein Eloquent) نامگذاری کند. مشکل اینجاست که پروژه اصلی بهاندازه کافی وقتگیر است و معین برای پیادهسازی ORM اختصاصیاش به زمان بیشتری نیاز دارد؛ از همین رو، او از شما کمک میخواهد تا در تکمیل این ORM همراهش باشید.

جزئیات پروژه🔗
پروژه اولیه را از این لینک دانلود کنید.
ساختار فایلها
راهاندازی پروژه
برای راهاندازی پروژه، به پایگاهداده MySQL نیاز است. در این بخش، به راهاندازی MySQL در داکر میپردازیم. اگر تاکنون داکر را نصب نکردهاید، بهکمک این لینک آن را نصب کنید.
برای نصب و راهاندازی کانتینر MySQL بهکمک داکر، دستور زیر را در ترمینال وارد کنید تا ایمیج MySQL دانلود شود و کانتینر راهاندازی شود:

terminal
وقتی مراحل نصب کامل شد، دستور زیر را در ترمینال وارد کنید تا با سرویس MySQL در کانتینر ساختهشده ارتباط برقرار کنید:

terminal
حال دستور زیر را در محیط تعاملی MySQL وارد کنید تا پایگاهداده testdb
استفاده شود:

sql
اکنون میتوانیم جدول users
را ایجاد کنیم؛ دستور زیر را وارد کنید تا جدول users
در پایگاهداده testdb
ساخته شود:

sql
این پروژه شامل ۵ فایل است که ۳ فایل از قبل تکمیل شدهاند. شما باید فایلهای Model.php
و QueryBuilder.php
را پیادهسازی کنید؛ در ادامه، جزئیات هرکدام از فایلها و متدهای آنها را میتوانید مشاهده کنید:
فایل Database.php
این فایل شامل یک کلاس بهنام Database
است که یک شی pdo
را مقداردهی اولیه میکند و میتوان با استفاده از Database::getInstance()
به آن دسترسی پیدا کرد. این فایل از قبل پیادهسازی شده و شما نیازی به تغییر در آن ندارید؛ در پروژه ارسالی شما، این فایل جایگزین میشود، بنابراین هر تغییری در آن ایجاد کنید، نادیده گرفته خواهد شد. اما اگر میخواهید نتایج کوئریهایتان ببینید، باید مقادیر موجود در این فایل را تغییر دهید تا بتوانید پروژه را روی سیستم خودتان اجرا کنید.

Database.php
فایل QueryBuilder.php
کلاس QueryBuilder
برای ساخت و اجرای کوئریهای پایگاهداده طراحی شده است. این کلاس امکاناتی مانند SELECT
، WHERE
، GROUP BY
، HAVING
، ORDER BY
، LIMIT
و عملیات CRUD را فراهم میکند. در پیادهسازی متدهای این کلاس، از دیزاین پترن Builder استفاده کنید.
متد select()
این متد تعیین میکند که کدام ستونها در نتایج SELECT
آورده شوند.
مثال🔗
متد where()
این متد برای افزودن شرطها به کوئریهای WHERE
استفاده میشود.
- امکان استفاده از عملگرهای مقایسهای (
=
, >
, <
, LIKE
، و ...) وجود دارد.
- در صورتی که فقط دو آرگومان به متد داده شود، عملگر مقایسهای پیشفرض (
=
) در نظر گرفته میشود.
مثال🔗
متد groupBy()
این متد کوئری را براساس یک یا چند ستون گروهبندی (GROUP BY
) میکند.
مثال🔗
متد having()
این متد برای فیلترکردن نتایج پس از GROUP BY
استفاده میشود.
مثال🔗
متد orderBy()
این متد چیدمان نتایج را براساس یک ستون و ترتیب ASC
یا DESC
تعیین میکند.
مثال🔗
متد limit()
این متد تعداد نتایج بازگشتی را محدود (LIMIT
) میکند.
مثال🔗
متد offset
این متد تعدادی از نتایج بازگشتی را رد (skip) میکند.
مثال🔗
متد get()
این متد کوئری نهایی را اجرا کرده و نتایج را بهصورت آرایهای از اشیا مدل برمیگرداند.
متد first()
این متد اولین نتیجهی کوئری را دریافت کرده و مقدار null
را در صورت خالیبودن بازمیگرداند.
مثال🔗
متد count()
این متد تعداد کل ردیفهای خروجی کوئری را برمیگرداند (COUNT(*)
).
مثال🔗
متدهای sum()
, avg()
, min()
, max()
این متدها مقدار مجموع، میانگین، حداقل و حداکثر یک ستون را محاسبه میکنند.
مثال🔗
متد insert()
این متد یک رکورد جدید در پایگاهداده درج (INSERT
) کرده و id
آن را برمیگرداند.
مثال🔗
متد update()
این متد دادههای جدول را بر اساس WHERE
بهروزرسانی میکند.
- اگر شرط
WHERE
تعیین نشده باشد، خطا (Exception
) ایجاد میشود.
مثال🔗
متد delete()
این متد رکوردهای پایگاهداده را حذف (DELETE
) میکند.
- اگر
WHERE
تعیین نشده باشد، عملیات متوقف شده و خطا (Exception
) صادر میشود.
مثال🔗
فایل Model.php
این فایل باید پیادهسازی شود. در این فایل یک کلاس انتزاعی (abstract) بهنام Model
وجود دارد که مدلهای پایگاهداده از آن ارثبری میکنند. این کلاس دو پراپرتی دارد؛ نام جدول و آرایه attributes
. نام جدول باید توسط مدلهایی که از این کلاس ارثبری میکنند Overwrite شود. آرایه attributes
برای ستکردن پراپرتیهای dynamic است. این کلاس دارای چند متد است که باید پیادهسازی شوند:
متد query()
این متد یک شیء از کلاس QueryBuilder
ایجاد کرده و برای اجرای کوئریهای پایگاهداده مورد استفاده قرار میگیرد.
متد allQuery()
این متد تمام رکوردهای موجود در جدول مرتبط با مدل را دریافت کرده و بهصورت آرایهای از اشیا برمیگرداند.
مثال🔗
متد findQuery()
این متد یک رکورد خاص را بر اساس مقدار id
جستوجو میکند.
- اگر رکوردی یافت شود، نمونهای از مدل را برمیگرداند.
- در غیر این صورت مقدار
null
برمیگردد.
مثال🔗
متد createQuery()
این متد یک رکورد جدید در جدول مرتبط با مدل ایجاد میکند.
- دادههای جدید را در پایگاهداده درج کرده و نمونهای از مدل را که شامل این دادهها است، برمیگرداند.
مثال🔗
متد firstQuery()
این متد اولین رکورد موجود در جدول را دریافت کرده و بهعنوان نمونهای از مدل برمیگرداند.
مثال🔗
متد hydrateQuery()
این متد یک نمونه از مدل را با دادههای ورودی مقداردهی میکند.
- برای پر کردن شیء مدل از یک آرایه داده استفاده میشود.
متد updateQuery()
این متد مقدار فیلدهای یک رکورد را بهروزرسانی میکند.
- رکورد مورد نظر باید در object و پایگاهداده همزمان بهروزرسانی شود.
- اگر بهروزرسانی موفقیتآمیز باشد، مقدار
true
برمیگردد.
- در غیر این صورت مقدار
false
بازمیگردد.
مثال🔗
متد deleteQuery()
این متد رکورد مربوطه را از پایگاهداده حذف میکند.
- اگر حذف موفقیتآمیز باشد، مقدار
true
برمیگردد.
- در غیر این صورت مقدار
false
بازمیگردد.
مثال🔗
فایل User.php
این فایل شامل یک کلاس User
است که از کلاس Model
ارثبری میکند. در این کلاس، صرفا مقادیر مورد نیاز تعریف یا مقداردهی شدهاند. شما نیازی به پیادهسازی این فایل ندارید.

User.php
فایل autoload.php
این فایل صرفا شامل یک رجیستر است که کلاسهای مورد نیاز را از فایلهای دیگر فراخوانی میکند. شما نیازی به پیادهسازی این فایل ندارید.

autoload.php
نکات🔗
- برای حل این سوال باید از دیزاین پترن Builder استفاده کنید.
- دقت کنید که صرفا تغییراتی که در فایلهای
QueryBuilder.php
و Model.php
ایجاد میکنید بررسی خواهند شد؛ تغییراتی که در فایلهای دیگر پروژه ایجاد میکنید در سیستم داوری نادیده گرفته خواهند شد.
آنچه باید آپلود کنید🔗
پس از پیادهسازی فایلهای مورد نیاز، فایلهای QueryBuilder.php
و Model.php
را بهصورت فایل Zip ارسال کنید.
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.