1. Go to this page and download the library: Download psf/framework 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/ */
psf / framework example snippets
use Psf\Enumerators\DBDriver;
return [
'environment' => 'dev', // 'prd' mantém o cache de rotas estático (limpe no deploy)
'db' => [
'default' => [
'driver' => DBDriver::MySQL, // MySQL, PostgreSQL, SQLServer ou SQLite
'hostname' => 'localhost', // 'host', 'user' e 'pass' também são aceitos
'username' => 'root',
'password' => '',
'database' => 'meu_banco', // SQLite: caminho do arquivo ou ':memory:'
'port' => 3306,
],
],
'jwt' => [
'secret' => 'uma-chave-longa-e-aleatoria', // mínimo de 16 caracteres
],
'settings' => [
'controllers' => [__DIR__ . '/app/Controllers'], // diretórios varridos em busca de #[Router]
'debug' => false, // true expõe mensagem/arquivo/linha dos erros de banco na resposta
'verifyauth' => [App\Auth::class, 'verify'], // usado pelo middleware 'authentication'
'docsapi' => 'api/docs', // opcional: página de documentação da API
'cors' => [
'origins' => ['https://app.exemplo.com'], // ou '*'
'credentials' => false,
],
],
];
sf\Http\{Http, Router};
PSF::init(['config' => __DIR__ . '/../config.php']);
try {
(new Router())->handle();
} catch (\Throwable $e) {
// O Router sinaliza 404 (rota não encontrada), 4xx do controller e 500 lançando
// exceções com o status HTTP no código. Sem este catch, elas chegam à página do Ignition.
$code = $e->getCode();
$status = is_int($code) && $code >= 400 && $code < 600 ? $code : 500;
Http::response($status < 500 ? $e->getMessage() : 'Erro interno', [], $status);
}
namespace App\Models;
use Psf\Model\{Model, ModelTrait};
use Psf\Model\Attributes\{Table, Column, PrimaryKey, Type, Nullable, Standard, ColumnCreatedDate, ColumnDeletedDate};
#[Table('usuarios')]
class Usuario extends Model
{
use ModelTrait; // find(), findById(), col(), createMany()
#[PrimaryKey, Column('id'), Type('INT UNSIGNED AUTO_INCREMENT')]
public ?int $id = null;
#[Column('nome'), Nullable(false), Type('VARCHAR(100) NOT NULL')]
public ?string $nome = null;
#[Column('status'), Standard('ativo'), Type('VARCHAR(20)')]
public ?string $status = null;
#[Column('created_at'), ColumnCreatedDate, Type('DATETIME')]
public ?string $createdAt = null;
#[Column('deleted_at'), ColumnDeletedDate, Type('DATETIME')] // delete() vira soft delete
public ?string $deletedAt = null;
}
namespace App\Controllers;
use App\Models\Usuario;
use Psf\Http\{Http, Router};
use Psf\Model\ControllerBase;
class UsuarioController extends ControllerBase
{
#[Router(method: 'GET', path: '/usuarios/{id:int}', version: 1)]
public function show(int $id)
{
$usuario = Usuario::findById($id);
if (!$usuario) {
Http::response('Usuário não encontrado', [], 404);
}
Http::response('OK', $usuario->toArray());
}
#[Router(method: 'POST', path: '/usuarios', version: 1, middlewares: ['authentication'], docs: [
'title' => 'Criar usuário',
'fields' => [['name' => 'nome', 'type' => 'string', '
namespace App;
use Psf\Http\RequestParser;
use Psf\Utils\JWT;
class Auth
{
public function verify(): object|bool
{
$token = RequestParser::extractBearerToken();
$payload = $token ? JWT::verify($token) : false; // valida assinatura, exp e nbf
return $payload ? (object) $payload : false;
}
}