Skip to content

Instantly share code, notes, and snippets.

@willitscale
Last active July 31, 2025 22:37
Show Gist options
  • Save willitscale/e54e548a80019b9922652d9920410685 to your computer and use it in GitHub Desktop.
Save willitscale/e54e548a80019b9922652d9920410685 to your computer and use it in GitHub Desktop.
Streetlamp Example
<?php
declare(strict_types=1);
namespace willitscale\Streetlamp\Ai\Controllers;
use willitscale\Streetlamp\Attributes\DataBindings\Json\JsonObject;
use willitscale\Streetlamp\Attributes\DataBindings\Json\JsonProperty;
#[JsonObject]
class AgeModel
{
public function __construct(
#[JsonProperty(true)]
private int $age = 0
) {
}
}
<?php
namespace willitscale\Streetlamp\Ai\Controllers;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class AuthMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
return $handler->handle($request);
}
}
<?php
declare(strict_types=1);
use willitscale\Streetlamp\Router;
require_once __DIR__ . '/vendor/autoload.php';
function dd(...$args): void
{
dump(...$args);
exit(1);
}
function dump(...$args): void
{
foreach ($args as $arg) {
var_dump($arg);
}
}
try {
new Router()->render();
} catch (Throwable $e) {
dd($e->getMessage());
}
<?php
declare(strict_types=1);
namespace willitscale\Streetlamp\Ai\Controllers;
use Psr\Http\Message\ResponseInterface;
use willitscale\Streetlamp\Attributes\Accepts;
use willitscale\Streetlamp\Attributes\Controller\RouteController;
use willitscale\Streetlamp\Attributes\Parameter\BodyParameter;
use willitscale\Streetlamp\Attributes\Parameter\FileParameter;
use willitscale\Streetlamp\Attributes\Parameter\HeaderParameter;
use willitscale\Streetlamp\Attributes\Parameter\PathParameter;
use willitscale\Streetlamp\Attributes\Parameter\PostParameter;
use willitscale\Streetlamp\Attributes\Parameter\QueryParameter;
use willitscale\Streetlamp\Attributes\Path;
use willitscale\Streetlamp\Attributes\Route\Method;
use willitscale\Streetlamp\Builders\ResponseBuilder;
use willitscale\Streetlamp\Enums\HttpMethod;
use willitscale\Streetlamp\Enums\HttpStatusCode;
use willitscale\Streetlamp\Enums\MediaType;
use willitscale\Streetlamp\Models\File;
use willitscale\Streetlamp\Models\ServerSentEvents\Data;
use willitscale\Streetlamp\Models\ServerSentEvents\Event;
use willitscale\Streetlamp\Models\ServerSentEvents\Id;
use willitscale\Streetlamp\Responses\ServerSentEventsDispatcher;
#[RouteController]
class MainController implements ServerSentEventsDispatcher
{
#[Method(HttpMethod::GET)]
#[Path('/query1')]
public function query1(
#[QueryParameter('name')] string $name = 'Unknown',
): ResponseInterface {
return new ResponseBuilder()
->setData('Hello, ' . $name)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::GET)]
#[Path('/query2')]
public function query2(
#[QueryParameter('name', true)] string $name = 'Unknown',
): ResponseInterface {
return new ResponseBuilder()
->setData('Hello, ' . $name)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::GET)]
#[Path('/path1/{name}')]
public function path1(
#[PathParameter('name', true)] string $name,
): ResponseInterface {
return new ResponseBuilder()
->setData('Hello, ' . $name)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::POST)]
#[Path('/post1')]
public function post1(
#[PostParameter('name', true)] string $name,
): ResponseInterface {
return new ResponseBuilder()
->setData('Hello, ' . $name)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::POST)]
#[Path('/post2')]
public function post2(
#[PostParameter('name', false)] string $name = 'Unknown',
): ResponseInterface {
return new ResponseBuilder()
->setData('Hello, ' . $name)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::GET)]
#[Path('/header1')]
public function header1(
#[HeaderParameter('name', true)] string $name,
): ResponseInterface {
return new ResponseBuilder()
->setData('Hello, ' . $name)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::GET)]
#[Path('/header2')]
public function header2(
#[HeaderParameter('name', false)] string $name = 'Unknown',
): ResponseInterface {
return new ResponseBuilder()
->setData('Hello, ' . $name)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::POST)]
#[Path('/body1')]
#[Accepts(MediaType::APPLICATION_JSON)]
public function body1(
#[BodyParameter] string $name,
): ResponseInterface {
return new ResponseBuilder()
->setData('Hello, ' . json_decode($name))
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::GET)]
#[Path('/file_upload')]
public function fileUpload(): ResponseInterface
{
return new ResponseBuilder()
->setData(
'<form action="/file1" method="post" enctype="multipart/form-data">
<div>
<label for="file">Choose file to upload</label>
<input type="file" id="file" name="file" multiple />
</div>
<div>
<button>Submit</button>
</div>
</form>'
)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::POST)]
#[Path('/file1')]
public function file1(
#[FileParameter('file')] File $file,
): ResponseInterface {
return new ResponseBuilder()
->setData($file)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::APPLICATION_JSON)
->build();
}
#[Method(HttpMethod::POST)]
#[Path('/data1')]
#[Accepts(MediaType::APPLICATION_JSON)]
public function data1(
#[BodyParameter] TestModel $data,
): ResponseInterface {
return new ResponseBuilder()
->setData($data)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::APPLICATION_JSON)
->build();
}
#[Method(HttpMethod::GET)]
#[Path('/sse-demo')]
public function sseDemo(): ResponseInterface
{
return new ResponseBuilder()
->setData(file_get_contents(__DIR__ . '/sse-demo.html'))
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_HTML)
->build();
}
#[Method(HttpMethod::GET)]
#[Path('/sse')]
public function sse(): ResponseInterface
{
return new ResponseBuilder()
->setStreamDispatcher($this)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::TEXT_EVENT_STREAM)
->build();
}
public function dispatch(): array
{
return [
new Id('123'),
new Event('ping'),
new Data(new TestModel("Test", "[email protected]", new AgeModel(12)))
];
}
public function isRunning(): bool
{
return true;
}
public function delay(): void
{
sleep(1);
}
}
<head>
<script>
function start_sse_test(){
const evtSource = new EventSource("/sse");
evtSource.onmessage = function(event) {
console.log(event);
const newElement = document.createElement("li");
var dataobj = JSON.parse(event.data);
console.log(dataobj);
newElement.textContent = "message: " + event.data;
eventList.appendChild(newElement);
}
}
</script>
</head>
<h1>Demo SSE HTML File</h1>
View source for details<br>
<button onClick="start_sse_test();return false;">Start SSE Test</button>
<button onClick="eventList.innerHTML = '';return false;">Clear</button>
<ul id="list">
</ul>
<script>
const eventList = document.getElementById("list");
</script>
<?php
declare(strict_types=1);
namespace willitscale\Streetlamp\Ai\Controllers;
use willitscale\Streetlamp\Ai\Controllers\AgeModel;
use willitscale\Streetlamp\Attributes\DataBindings\Json\JsonIgnore;
use willitscale\Streetlamp\Attributes\DataBindings\Json\JsonObject;
use willitscale\Streetlamp\Attributes\DataBindings\Json\JsonProperty;
use willitscale\Streetlamp\Attributes\Validators\AlphabeticValidator;
#[JsonObject]
class TestModel
{
public function __construct(
#[JsonProperty(true)] #[AlphabeticValidator] private string $name,
#[JsonProperty(false)] #[JsonIgnore] private string $email,
#[JsonProperty] private AgeModel $data
) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment