1. Go to this page and download the library: Download ray/media-query library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
ray / media-query example snippets
interface TodoAddInterface
{
#[DbQuery('user_add')]
public function add(string $id, string $title): void;
}
use Ray\AuraSqlModule\AuraSqlModule;
use Ray\MediaQuery\DbQueryConfig;
use Ray\MediaQuery\MediaQueryModule;
use Ray\MediaQuery\Queries;
protected function configure(): void
{
$this->install(
new MediaQueryModule(
Queries::fromDir('/path/to/queryInterface'),
new DbQueryConfig('/path/to/sql')
),
);
$this->install(new AuraSqlModule('mysql:host=localhost;dbname=test', 'username', 'password'));
}
class Todo
{
public function __construct(
private TodoAddInterface $todoAdd
) {}
public function add(string $id, string $title): void
{
$this->todoAdd->add($id, $title);
}
}
interface TodoItemInterface
{
#[DbQuery('todo_item', type: 'row')]
public function item(string $id): array;
#[DbQuery('todo_list')]
/** @return array<Todo> */
public function list(string $id): array;
}
interface TodoItemInterface
{
#[DbQuery('todo_item')]
public function item(string $id): Todo;
#[DbQuery('todo_list')]
/** @return array<Todo> */
public function list(string $id): array;
}
final class Todo
{
public readonly string $id;
public readonly string $title;
}
final class Invoice
{
public readonly string $userName;
public readonly string $emailAddress;
public function __construct(
public readonly string $id, // Single word - direct mapping
public readonly string $title, // Single word - direct mapping
string $user_name, // Multi-word - explicit assignment
string $email_address, // Multi-word - explicit assignment
) {
$this->userName = $user_name;
$this->emailAddress = $email_address;
}
}
final readonly class Invoice
{
public string $userName;
public string $emailAddress;
public function __construct(
public string $id, // Single word - direct mapping
public string $title, // Single word - direct mapping
string $user_name, // Multi-word - explicit assignment
string $email_address, // Multi-word - explicit assignment
) {
$this->userName = $user_name;
$this->emailAddress = $email_address;
}
}
interface UserInterface
{
#[DbQuery('user_list')]
/** @return array<Invoice> */
public function getUsers(): array;
}
// SQL file: user_list.sql
// SELECT id, title, user_name, email_address FROM invoices
// PDO::FETCH_CLASS works directly - constructor parameters match column names!
// - id → $id (direct)
// - title → $title (direct)
// - user_name → $user_name parameter → $userName property
// - email_address → $email_address parameter → $emailAddress property
final class Todo
{
public function __construct(
public readonly string $id,
public readonly string $title
) {}
}
interface TodoItemInterface
{
#[DbQuery('todo_item', factory: TodoEntityFactory::class)]
public function item(string $id): Todo;
#[DbQuery('todo_list', factory: TodoEntityFactory::class)]
/** @return array<Todo> */
public function list(string $id): array;
}
final class TodoEntityFactory
{
public static function factory(string $id, string $name): Todo
{
return new Todo($id, $name);
}
}
final class TodoEntityFactory
{
public function __construct(
private HelperInterface $helper
){}
public function factory(string $id, string $name): Todo
{
return new Todo($id, $this->helper($name));
}
}
final class OrderEntityFactory
{
public function factory(string $id, float $amount): Order
{
return new Order(
id: $id,
amount: $amount,
tax: $amount * 0.1, // Computed tax
total: $amount * 1.1, // Computed total
);
}
}
final class UserEntityFactory
{
public function __construct(
private EmailValidator $emailValidator, // Injected by DI
) {}
public function factory(string $id, string $first_name, string $last_name, string $email): User
{
return new User(
id: $id,
firstName: $first_name,
lastName: $last_name,
fullName: "$first_name $last_name", // Computed
email: $this->emailValidator->validate($email), // Validated with DI service
);
}
}
interface TaskAddInterface
{
#[DbQuery('task_add')]
public function __invoke(string $title, DateTimeInterface $cratedAt = null): void;
}
interface MemoAddInterface
{
#[DbQuery('memo_add')]
public function __invoke(string $memo, UserId $userId = null): void;
}
class UserId implements ToScalarInterface
{
public function __construct(
private LoginUser $user;
){}
public function toScalar(): int
{
return $this->user->id;
}
}
public function __invoke(Uuid $uuid = null): void; // UUID is generated and passed.
use Ray\InputQuery\Attribute\Input;
final class UserInput
{
public function __construct(
#[Input] public readonly string $givenName,
#[Input] public readonly string $familyName,
#[Input] public readonly string $email
) {}
}
final class TodoCreateInput
{
public function __construct(
#[Input] public readonly string $title,
#[Input] public readonly UserInput $assignee, // nested input
#[Input] public readonly ?DateTimeInterface $dueDate
) {}
}
interface TodoInterface
{
#[DbQuery('todo_create')]
public function create(TodoCreateInput $input): void;
}
use Ray\MediaQuery\PagesInterface;
interface TodoList
{
#[DbQuery('todo_list'), Pager(perPage: 10, template: '/{?page}')]
public function __invoke(): PagesInterface;
}
#[DbQuery('todo_list'), Pager(perPage: 'pageNum', template: '/{?page}')]
public function __invoke($pageNum): Pages;
$pages = ($todoList)();
$cnt = count($page); // When count() is called, the count SQL is generated and queried.
$page = $pages[2]; // A page query is executed when an array access is made.
// $page->data // sliced data
// $page->current;
// $page->total
// $page->hasNext
// $page->hasPrevious
// $page->maxPerPage;
// (string) $page // pager html
#[DbQuery('todo_list'), Pager(perPage: 'pageNum', template: '/{?page}')]
/** @return array<Todo> */
public function __invoke($pageNum): Pages;
class TodoItem implements TodoItemInterface
{
public function __construct(
private SqlQueryInterface $sqlQuery
){}
public function __invoke(string $id) : array
{
return $this->sqlQuery->getRow('todo_item', ['id' => $id]);
}
}
$sqlQuery->getRow($queryId, $params); // Result is a single row
$sqlQuery->getRowList($queryId, $params); // result is multiple rows
$statement = $sqlQuery->getStatement(); // Retrieve the PDO Statement
$pages = $sqlQuery->getPages(); // Get the pager
public function testAdd(): void
{
$this->sqlQuery->exec('todo_add', $todoRun);
$this->assertStringContainsString('query: todo_add({"id": "1", "title": "run"})', (string) $this->log);
}
use Ray\MediaQuery\MediaQuerySqlTemplateModule;
protected function configure(): void
{
// Default template: "-- {{ id }}.sql\n{{ sql }}"
$this->install(new MediaQuerySqlTemplateModule());
// Custom template with application name
$this->install(new MediaQuerySqlTemplateModule("-- MyApp: {{ id }}.sql\n{{ sql }}"));
}
use Ray\MediaQuery\Annotation\DbQuery;
#[DbQuery('user_add')]
public function add(string $id, string $title): void;