1. Go to this page and download the library: Download ray/input-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 / input-query example snippets
// HTTP Request: ?name=John&[email protected]&addressStreet=123 Main St&addressCity=Tokyo
// Automatically becomes:
final class AddressInput {
public function __construct(
#[Input] public readonly string $street,
#[Input] public readonly string $city
) {}
}
final class UserInput {
public function __construct(
#[Input] public readonly string $name,
#[Input] public readonly string $email,
#[Input] public readonly AddressInput $address // Nested object!
) {}
}
$user = $inputQuery->newInstance(UserInput::class, $_GET);
echo $user->name; // "John"
echo $user->address->street; // "123 Main St"
use Ray\InputQuery\Attribute\Input;
final class UserInput
{
public function __construct(
#[Input] public readonly string $name,
#[Input] public readonly string $email
) {}
}
use Ray\InputQuery\InputQuery;
use Ray\Di\Injector;
$injector = new Injector();
$inputQuery = new InputQuery($injector);
// Create object directly from array
$user = $inputQuery->newInstance(UserInput::class, [
'name' => 'John Doe',
'email' => '[email protected]'
]);
echo $user->name; // John Doe
echo $user->email; // [email protected]
// Method argument resolution from $_POST
$method = new ReflectionMethod(UserController::class, 'register');
$args = $inputQuery->getArguments($method, $_POST);
$result = $method->invokeArgs($controller, $args);
final class AddressInput
{
public function __construct(
#[Input] public readonly string $street,
#[Input] public readonly string $city,
#[Input] public readonly string $zip
) {}
}
final class UserInput
{
public function __construct(
#[Input] public readonly string $name,
#[Input] public readonly string $email,
#[Input] public readonly AddressInput $address // Nested input
) {}
}
$user = $inputQuery->newInstance(UserInput::class, [
'name' => 'John Doe',
'email' => '[email protected]',
'addressStreet' => '123 Main St',
'addressCity' => 'Tokyo',
'addressZip' => '100-0001'
]);
echo $user->name; // John Doe
echo $user->address->street; // 123 Main St
use Ray\InputQuery\Attribute\Input;
final class UserInput
{
public function __construct(
#[Input] public readonly string $id,
#[Input] public readonly string $name
) {}
}
final class UserListController
{
/**
* @param list<UserInput> $users
*/
public function updateUsers(
#[Input(item: UserInput::class)] array $users // Array of UserInput objects
) {
foreach ($users as $user) {
echo $user->name; // Each element is a UserInput instance
}
}
/**
* @param ArrayObject<int, UserInput> $users
*/
public function processUsers(
#[Input(item: UserInput::class)] ArrayObject $users // ArrayObject collection
) {
// $users is an ArrayObject containing UserInput instances
}
}
$data = [
'hobbies' => ['music', 'sports'], // Only checked values
'categories' => ['tech', 'lifestyle'] // Only selected values
];
// In your controller
/**
* @param list<string> $hobbies
* @param list<string> $categories
*/
public function updatePreferences(
#[Input] array $hobbies, // Simple string array
#[Input] array $categories // Simple string array
) {
// Direct array of strings, no object conversion needed
}
final class UserCollection extends ArrayObject
{
public function getFirst(): ?UserInput
{
return $this[0] ?? null;
}
}
/**
* @param array<UserInput> $users
*/
public function handleUsers(
#[Input(item: UserInput::class)] UserCollection $users
) {
$firstUser = $users->getFirst(); // Custom method available
}
use Ray\Di\Di\Named;
interface AddressServiceInterface
{
public function findByZip(string $zip): Address;
}
interface TicketFactoryInterface
{
public function create(string $eventId, string $ticketId): Ticket;
}
final class EventBookingInput
{
public function __construct(
#[Input] public readonly string $ticketId, // From query - raw ID
#[Input] public readonly string $email, // From query
#[Input] public readonly string $zip, // From query
#[Named('event_id')] private string $eventId, // From DI
private TicketFactoryInterface $ticketFactory, // From DI
private AddressServiceInterface $addressService, // From DI
) {
// Create complete Ticket object from ID (rface::class)->to(TicketFactory::class); // Can swap with mock in tests
$this->bind(AddressServiceInterface::class)->to(AddressService::class);
$this->bind()->annotatedWith('event_id')->toInstance('ray-event-2025');
}
});
$inputQuery = new InputQuery($injector);
// Usage - Factory automatically creates complete objects from IDs
try {
$booking = $inputQuery->newInstance(EventBookingInput::class, [
'ticketId' => 'TKT-2024-001',
'email' => '[email protected]',
'zip' => '100-0001'
]);
// $booking->ticket is a Ticket object with ID and validation status
echo "Ticket ID: " . $booking->ticket->id; // Only valid ticket ID
} catch (InvalidTicketException $e) {
// Handle expired or invalid tickets
echo "Booking failed: " . $e->getMessage();
}
use Ray\InputQuery\InputQuery;
use Ray\InputQuery\FileUploadFactory;
$inputQuery = new InputQuery($injector, new FileUploadFactory());
use Koriym\FileUpload\FileUpload;
use Koriym\FileUpload\ErrorFileUpload;
use Ray\InputQuery\Attribute\InputFile;
final class UserProfileInput
{
public function __construct(
#[Input] public readonly string $name,
#[Input] public readonly string $email,
#[InputFile(
maxSize: 5 * 1024 * 1024, // 5MB
allowedTypes: ['image/jpeg', 'image/png'],
allowedExtensions: ['jpg', 'jpeg', 'png']
)]
public readonly FileUpload|ErrorFileUpload $avatar,
#[InputFile] public readonly FileUpload|ErrorFileUpload|null $banner = null,
) {}
}
final class GalleryInput
{
/**
* @param list<FileUpload|ErrorFileUpload> $images
*/
public function __construct(
#[Input] public readonly string $title,
#[InputFile(
maxSize: 10 * 1024 * 1024, // 10MB per file
allowedTypes: ['image/*']
)]
public readonly array $images,
) {}
}
// Method usage example
class GalleryController
{
public function createGallery(GalleryInput $input): void
{
$savedImages = [];
foreach ($input->images as $image) {
if ($image instanceof FileUpload) {
$savedImages[] = $this->saveFile($image, 'gallery/');
} elseif ($image instanceof ErrorFileUpload) {
// Log error but continue with other images
$this->logger->warning('Image upload failed: ' . $image->message);
}
}
$this->galleryService->create($input->title, $savedImages);
}
}
// Production usage - FileUpload library handles multiple files automatically
$input = $inputQuery->newInstance(GalleryInput::class, $_POST);
// Array of FileUpload objects created automatically from uploaded files
// Testing usage - inject array of mock FileUpload objects for easy testing
$mockImages = [
FileUpload::create(['name' => 'image1.jpg', ...]),
FileUpload::create(['name' => 'image2.png', ...])
];
$input = $inputQuery->newInstance(GalleryInput::class, [
'title' => 'My Gallery',
'images' => $mockImages
]);
use Ray\InputQuery\ToArray;
final class CustomerInput
{
public function __construct(
#[Input] public readonly string $name,
#[Input] public readonly string $email,
) {}
}
final class OrderInput
{
public function __construct(
#[Input] public readonly string $id,
#[Input] public readonly CustomerInput $customer,
#[Input] public readonly array $items,
) {}
}
// Create nested input object
$orderInput = new OrderInput(
id: 'ORD-001',
customer: new CustomerInput(name: 'John Doe', email: '[email protected]'),
items: [['product' => 'laptop', 'quantity' => 1]]
);
// Convert to flat array for SQL
$toArray = new ToArray();
$params = $toArray($orderInput);
// Result:
// [
// 'id' => 'ORD-001',
// 'name' => 'John Doe', // Flattened from customer
// 'email' => '[email protected]', // Flattened from customer
// 'items' => [['product' => 'laptop', 'quantity' => 1]] // Arrays preserved
// ]
// Using with Aura.Sql
$sql = "INSERT INTO orders (id, customer_name, customer_email) VALUES (:id, :name, :email)";
$statement = $pdo->prepare($sql);
$statement->execute($params);
// Arrays are preserved for IN clauses
$productIds = $params['productIds']; // [1, 2, 3]
$sql = "SELECT * FROM products WHERE id IN (?)";
$statement = $pdo->prepare($sql);
$statement->execute([$productIds]); // Aura.Sql handles array expansion
// Other use cases
return new JsonResponse($params); // API responses
$this->logger->info('Order data', $params); // Logging
final class OrderInput
{
public function __construct(
#[Input] public readonly string $id, // 'ORD-001'
#[Input] public readonly CustomerInput $customer, // Has 'id' property: 'CUST-123'
) {}
}
$params = $toArray($orderInput);
// Result: ['id' => 'CUST-123'] // Customer ID overwrites order ID
final class AddressInput
{
public function __construct(
#[Input] public readonly string $street,
#[Input] public readonly string $city,
#[Input] public readonly string $country,
) {}
}
final class CustomerInput
{
public function __construct(
#[Input] public readonly string $name,
#[Input] public readonly string $email,
#[Input] public readonly AddressInput $address,
) {}
}
final class OrderInput
{
public function __construct(
#[Input] public readonly string $orderId,
#[Input] public readonly CustomerInput $customer,
#[Input] public readonly AddressInput $shipping,
#[Input] public readonly array $productIds,
) {}
}
$order = new OrderInput(
orderId: 'ORD-001',
customer: new CustomerInput(
name: 'John Doe',
email: '[email protected]',
address: new AddressInput(street: '123 Main St', city: 'Tokyo', country: 'Japan')
),
shipping: new AddressInput(street: '456 Oak Ave', city: 'Osaka', country: 'Japan'),
productIds: ['PROD-1', 'PROD-2', 'PROD-3']
);
$params = $toArray($order);
// Result:
// [
// 'orderId' => 'ORD-001',
// 'name' => 'John Doe',
// 'email' => '[email protected]',
// 'street' => '456 Oak Ave', // Shipping address overwrites customer address
// 'city' => 'Osaka', // Shipping address overwrites customer address
// 'country' => 'Japan', // Same value, so no visible conflict
// 'productIds' => ['PROD-1', 'PROD-2', 'PROD-3'] // Array preserved
// ]
// Use the flattened data
$orderId = $params['orderId'];
$customerName = $params['name'];
$shippingAddress = "{$params['street']}, {$params['city']}, {$params['country']}";
$productIds = $params['productIds']; // Array preserved
bash
# Basic examples with nested objects and DI
php demo/run.php
# Array processing demo
php demo/ArrayDemo.php
# CSV file processing with batch operations
php demo/csv/run.php
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.