ALTIDO é uma estrutura de PHP leve. Crie facilmente e rapidamente aplicativos Web RESTful de alto desempenho. Librarias de roteamento, banco de dados, cache, manuseio de erros, log e agendamento de empregos. Concentre -se na criação de soluções para o processo principal de aplicativos da Web. Mantenha -se simples e extensível.
| Projeto | Descrição |
|---|---|
| Desembarque | Estrutura básica de roteamento interno, banco de dados, cache, etc. |
| ADLY-ADMIN | Uma extensão completa do painel de administração com base em acordados. Não é necessária codificação front-end. |
| Projeto ALTY | Um modelo para iniciantes criar aplicativos da Web facilmente por ALGE/ALGADO-ADMIN. |
Php 7.4+
Não tem compositor? Instale o compositor primeiro.
$ composer create-project juneszh/alight-project {PROJECT_DIRECTORY}O modelo de projeto contém estrutura de pasta comum, adequada para o padrão MVC, consulte: ALTOD-PROJETO.
É fácil personalizar pastas modificando a configuração. Mas os seguintes tutoriais são baseados na configuração do modelo.
Exemplo Nginx (Nginx 1.17.10, Php 7.4.3, Ubuntu 20.04.3):
server {
listen 80 ;
listen [::]:80;
root /var/www/{PROJECT_DIRECTORY}/public;
index index.php;
server_name {YOUR_DOMAIN};
location / {
try_files $uri $uri / /index.php? $query_string ;
}
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
}Todas as opções de configuração para a estrutura ALGE serão importadas do arquivo 'config/app.php', que você precisa criar. Por exemplo:
Arquivo: config/app.php
<?php
return [
' app ' => [
' debug ' => false ,
' timezone ' => ' Europe/Kiev ' ,
' storagePath ' => ' storage ' ,
' domainLevel ' => 2 ,
' corsDomain ' => null ,
' corsHeaders ' => null ,
' corsMethods ' => null ,
' cacheAdapter ' => null ,
' errorHandler ' => null ,
' errorPageHandler ' => null ,
],
' route ' => ' config/route/web.php ' ,
' database ' => [
' type ' => ' mysql ' ,
' host ' => ' 127.0.0.1 ' ,
' database ' => ' alight ' ,
' username ' => ' root ' ,
' password ' => '' ,
],
' cache ' => [
' type ' => ' file ' ,
],
' job ' => ' config/job.php ' ,
]; <?php
Alight Config:: get ( ' app ' );
Alight Config:: get ( ' app ' , ' storagePath ' );Consulte Config.php para obter detalhes.
Antes de aprender regras de roteamento, você precisa criar um arquivo PHP primeiro que armazena regras de roteamento. Como o cache de roteamento é atualizado ou não, ele é baseado no tempo de modificação do arquivo de roteamento. Por exemplo:
Arquivo: Config/Route/Web.php
Alight Route:: get ( ' / ' , ' Controller::index ' );Arquivo: config/app.php
<?php
return [
' route ' => ' config/route/web.php '
// Also supports multiple files
// 'route' => ['config/route/web.php', config/route/api.php']
];A propósito, a configuração da rota suporta a importação de arquivos especificados para subdomínios :
<?php
return [
' route ' => [
//Import on any request
' * ' => ' config/route/web.php ' ,
//Import when requesting admin.yourdomain.com
' admin ' => ' config/route/admin.php ' ,
//Import multiple files when requesting api.yourdomain.com
' api ' => [ ' config/route/api.php ' , ' config/route/api_mobile.php ' ],
]
]; Alight Route:: get ( $ pattern , $ handler );
// Example
Alight Route:: get ( ' / ' , ' Controller::index ' );
Alight Route:: get ( ' / ' , [ ' Controller ' , ' index ' ]);
// Or try this to easy trigger hints from IDE
Alight Route:: get ( ' / ' , [Controller::class, ' index ' ]);
// With default args
Alight Route:: get ( ' post/list[/{page}] ' , [Controller::class, ' list ' ], [ ' page ' => 1 ]);
// Common HTTP request methods
Alight Route:: options ( ' / ' , ' handler ' );
Alight Route:: head ( ' / ' , ' handler ' );
Alight Route:: post ( ' / ' , ' handler ' );
Alight Route:: delete ( ' / ' , ' handler ' );
Alight Route:: put ( ' / ' , ' handler ' );
Alight Route:: patch ( ' / ' , ' handler ' );
// Map for Custom methods
Alight Route:: map ([ ' GET ' , ' POST ' ], ' test ' , ' handler ' );
// Any for all common methods
Alight Route:: any ( ' test ' , ' handler ' ); // Matches /user/42, but not /user/xyz
Alight Route:: get ( ' user/{id:d+} ' , ' handler ' );
// Matches /user/foobar, but not /user/foo/bar
Alight Route:: get ( ' user/{name} ' , ' handler ' );
// Matches /user/foo/bar as well, using wildcards
Alight Route:: get ( ' user/{name:.+} ' , ' handler ' );
// The /{name} suffix is optional
Alight Route:: get ( ' user[/{name}] ' , ' handler ' );
// Root wildcards for single page app
Alight Route:: get ( ' /{path:.*} ' , ' handler ' );Nikic/Route Fast lida com todas as expressões regulares no caminho de roteamento. Veja o uso do Fastoute para obter detalhes.
Alight Route:: group ( ' admin ' );
// Matches /admin/role/list
Alight Route:: get ( ' role/list ' , ' handler ' );
// Matches /admin/role/info
Alight Route:: get ( ' role/info ' , ' handler ' );
// Override the group
Alight Route:: group ( ' api ' );
// Matches /api/news/list
Alight Route:: get ( ' news/list ' , ' handler ' ); Você pode personalizar os métodos contidos na AlightRoute::any() .
Alight Route:: setAnyMethods ([ ' GET ' , ' POST ' ]);
Alight Route:: any ( ' only/get/and/post ' , ' handler ' );Se você deseja executar algum código comum antes do manipulador da Route.
// For example log every hit request
Alight Route:: beforeHandler ([ svc Request::class, ' log ' ]);
Alight Route:: get ( ' test ' , ' handler ' );
Alight Route:: post ( ' test ' , ' handler ' );Não recomendado, mas se o seu código exigir:
// Effective in the current route file
Alight Route:: disableCache (); Todas as opções de roteamento apenas entram em vigor no arquivo atual e serão redefinidas automaticamente por AlightRoute::init() antes que o próximo arquivo seja importado. Por exemplo:
Arquivo: config/admin.php
Alight Route:: group ( ' admin ' );
Alight Route:: setAnyMethods ([ ' GET ' , ' POST ' ]);
// Matches '/admin/login' by methods 'GET', 'POST'
Alight Route:: any ( ' login ' , ' handler ' );Arquivo: config/web.php
// Matches '/login' by methods 'GET', 'POST', 'PUT', 'DELETE', etc
Alight Route:: any ( ' login ' , ' handler ' );Envie um cabeçalho de controle de cache para controlar o cache em navegadores e caches compartilhados (CDN) para otimizar a velocidade do acesso a dados não modificados.
// Cache one day
Alight Route:: get ( ' about/us ' , ' handler ' )-> cache ( 86400 );
// Or force disable cache
Alight Route:: put ( ' user/info ' , ' handler ' )-> cache ( 0 );Fornecemos um manipulador de autorização simples para gerenciar o status de login do usuário.
// Define a global authorization verification handler
Alight Route:: authHandler ([ svc Auth::class, ' verify ' ]);
// Enable verification in routes
Alight Route:: get ( ' user/info ' , ' handler ' )-> auth ();
Alight Route:: get ( ' user/password ' , ' handler ' )-> auth ();
// No verification by default
Alight Route:: get ( ' about/us ' , ' handler ' );
// In general, routing with authorization will not use browser cache
// So auth() has built-in cache(0) to force disable cache
// Please add cache(n) after auth() to override the configuration if you need
Alight Route:: get ( ' user/rank/list ' , ' handler ' )-> auth ()-> cache ( 3600 );Arquivo: App/Service/Auth.php
namespace svc ;
class Auth
{
public static function verify ()
{
// Some codes about get user session from cookie or anywhere
// Returns the user id if authorization is valid
// Otherwise returns 0 or something else for failure
// Then use Router::getAuthId() in the route handler to get this id again
return $ userId ;
}
}Muitas vezes, os dados enviados pelo usuário levam tempo para processar e não queremos receber os mesmos dados antes de serem processados. Portanto, precisamos definir o tempo de recarga da solicitação. O usuário receberá um erro 429 ao solicitar novamente dentro da recarga.
// Cooldown only takes effect when authorized
Alight Route:: put ( ' user/info ' , ' handler ' )-> auth ()-> cd ( 2 );
Alight Route:: post ( ' user/status ' , ' handler ' )-> auth ()-> cd ( 2 );Quando sua API precisa ser usada para solicitações do AJAX por um site de terceiros (ou seu projeto possui vários domínios), você precisa enviar um conjunto de cabeçalhos da CORS. Por razões específicas, consulte: Mozilla Docs.
// Domains in config will receive the common cors header
Alight Route:: put ( ' share/config ' , ' handler ' )-> cors ();
// The specified domain will receive the common cors header
Alight Route:: put ( ' share/specified ' , ' handler ' )-> cors ( ' abc.com ' );
// The specified domain will receive the specified cors header
Alight Route:: put ( ' share/specified2 ' , ' handler ' )-> cors ( ' abc.com ' , ' Authorization ' , [ ' GET ' , ' POST ' ]);
// All domains will receive a 'Access-Control-Allow-Origin: *' header
Alight Route:: put ( ' share/all/http ' , ' handler ' )-> cors ( ' * ' );
// All domains will receive a 'Access-Control-Allow-Origin: [From Origin]' header
Alight Route:: put ( ' share/all/https ' , ' handler ' )-> cors ( ' origin ' );Se o seu site estiver usando a CDN, use este utilitário com cuidado. Para evitar a solicitação de falha após o cabeçalho ser armazenado em cache pelo CDN.
ALTE passa a configuração do 'banco de dados' para o Catfan/Medoo diretamente. Para opções de configuração específicas, consulte o Medoo. Por exemplo:
Arquivo: config/app.php
<?php
return [
' database ' => [
' type ' => ' mysql ' ,
' host ' => ' 127.0.0.1 ' ,
' database ' => ' alight ' ,
' username ' => ' root ' ,
' password ' => '' ,
],
// Multiple databases (The first database is default)
// 'database' => [
// 'main' => [
// 'type' => 'mysql',
// 'host' => '127.0.0.1',
// 'database' => 'alight',
// 'username' => 'root',
// 'password' => '',
// ],
// 'remote' => [
// 'type' => 'mysql',
// 'host' => '1.1.1.1',
// 'database' => 'alight',
// 'username' => 'root',
// 'password' => '',
// ],
// ]
]; AlightDatabase::init() é uma implementação estática e única de instância de new MedooMedoo() , por isso herda todas as funções do Medoo() . A instância única faz com que cada solicitação se conecte ao banco de dados apenas uma vez e reutilize -a, reduzindo efetivamente o número de conexões de banco de dados.
// Initializes the default database
$ db = Alight Database:: init ();
// Initializes others database with key
$ db2 = Alight Database:: init ( ' remote ' );
$ userList = $ db -> select ( ' user ' , ' * ' , [ ' role ' => 1 ]);
$ userInfo = $ db -> get ( ' user ' , ' * ' , [ ' id ' => 1 ]);
$ db -> insert ( ' user ' , [ ' name ' => ' anonymous ' , ' role ' => 2 ]);
$ id = $ db -> id ();
$ result = $ db -> update ( ' user ' , [ ' name ' => ' alight ' ], [ ' id ' => $ id ]);
$ result -> rowCount ();Consulte a documentação do Medoo para detalhes de uso.
O ABLY suporta vários drivers de cache e várias interfaces de cache com Symfony/Cache . As opções de configuração 'DSN' e 'Options' serão passadas para o adaptador de cache, mais detalhes, consulte os adaptadores de cache disponíveis. Por exemplo:
Arquivo: config/app.php
<?php
return [
' cache ' => [
' type ' => ' file ' ,
],
// Multiple cache (The first cache is the default)
// 'cache' => [
// 'file' => [
// 'type' => 'file',
// ],
// 'memcached' => [
// 'type' => 'memcached',
// 'dsn' => 'memcached://localhost',
// 'options' => [],
// ],
// 'redis' => [
// 'type' => 'redis',
// 'dsn' => 'redis://localhost',
// 'options' => [],
// ],
// ]
]; Assim como o banco de dados, AlightCache::init() é uma implementação estática e única de instância do cliente do cache para melhorar o desempenho da solicitação simultânea.
// Initializes the default cache
$ cache = Alight Cache:: init ();
// Initializes others cache with key
$ cache2 = Alight Cache:: init ( ' redis ' );
// Use SimpleCache(PSR-16) interface
if (! $ cache -> has ( ' test ' )){
$ cache -> set ( ' test ' , ' hello world! ' , 3600 );
}
$ cacheData = $ cache -> get ( ' test ' );
$ cache -> delete ( ' test ' ); $ cache6 = Alight Cache:: psr6 ( ' memcached ' );
$ cacheItem = $ cache6 -> getItem ( ' test ' );
if (! $ cacheItem -> isHit ()){
$ cacheItem -> expiresAfter ( 3600 );
$ cacheItem -> set ( ' hello world! ' );
// Bind to a tag
$ cacheItem -> tag ( ' alight ' );
}
$ cacheData = $ cacheItem -> get ();
$ cache6 -> deleteItem ( ' test ' );
// Delete all cached items in the same tag
$ cache6 -> invalidateTags ( ' alight ' )
// Or symfony/cache adapter style
$ cacheData = $ cache6 -> get ( ' test ' , function ( $ item ){
$ item -> expiresAfter ( 3600 );
return ' hello world! ' ;
});
$ cache6 -> delete ( ' test ' );Também suporta interfaces nativas de memcach e redis para usar o cache avançado:
$ memcached = Alight Cache:: memcached ( ' memcached ' );
$ memcached -> increment ( ' increment ' );
$ redis = Alight Cache:: redis ( ' redis ' );
$ redis -> lPush ( ' list ' , ' first ' );O Symfony/Cache suporta mais de 10 adaptadores, mas só temos 3 comuns, como sistema de arquivos, memcached, redis. Se você precisar de mais adaptadores, poderá expandi -lo. Por exemplo:
Arquivo: config/app.php
<?php
return [
' app ' => [
' cacheAdapter ' => [ svc Cache::class, ' adapter ' ],
],
' cache ' => [
// ...
' apcu ' => [
' type ' => ' apcu '
],
' array ' => [
' type ' => ' array ' ,
' defaultLifetime ' => 3600
]
]
];Arquivo: App/Service/Cache.php
namespace svc ;
use Symfony Component Cache Adapter ApcuAdapter ;
use Symfony Component Cache Adapter ArrayAdapter ;
use Symfony Component Cache Adapter NullAdapter ;
class Cache
{
public static function adapter ( array $ config )
{
switch ( $ config [ ' type ' ]) {
case ' apcu ' :
return new ApcuAdapter ();
break ;
case ' array ' :
return new ArrayAdapter ( $ config [ ' defaultLifetime ' ]);
default :
return new NullAdapter ();
break ;
}
}
}Consulte o componente Symfony Cache para obter mais informações.
ALTIDA captura todos os erros por meio do AlightApp::start() . Ao ativar o 'Debug' na configuração do aplicativo, os erros serão emitidos em Pretty HTML (por Filp/Whoops ) ou JSON.
Arquivo: config/app.php
<?php
return [
' app ' => [
' debug ' => true ,
]
];Ao desativar o 'Debug' no ambiente de produção, apenas registra erros para arquivar e produzir o status HTTP. Você pode substituir esses comportamentos padrão pela configuração do aplicativo. Por exemplo:
Arquivo: config/app.php
<?php
return [
' app ' => [
' errorHandler ' => [ svc Error::class, ' catch ' ],
' errorPageHandler ' => [ svc Error::class, ' page ' ],
]
];Arquivo: App/Service/Error.php
namespace svc ;
class Error
{
public static function catch ( Throwable $ exception )
{
// Some code like sending an email or using Sentry or something
}
public static function page ( int $ status )
{
switch ( $ status ) {
case 400 :
// Page code...
break ;
case 401 :
// Page code...
break ;
case 403 :
// Page code...
break ;
case 404 :
// Page code...
break ;
case 500 :
// Page code...
break ;
default :
// Page code...
break ;
}
}
}Se você precisar executar scripts PHP em segundo plano periodicamente.
$ sudo contab -eAdicione o seguinte à linha final:
* * * * * sudo -u www-data /usr/bin/php /var/www/{PROJECT_DIRECTORY}/app/scheduler.php >> /dev/null 2>&1Arquivo: Config/Job.php
Alight Job:: call ( ' handler ' )-> minutely ();
Alight Job:: call ( ' handler ' )-> hourly ();
Alight Job:: call ( ' handler ' )-> daily ();
Alight Job:: call ( ' handler ' )-> weekly ();
Alight Job:: call ( ' handler ' )-> monthly ();
Alight Job:: call ( ' handler ' )-> yearly ();
Alight Job:: call ( ' handler ' )-> everyMinutes ( 5 );
Alight Job:: call ( ' handler ' )-> everyHours ( 2 );
Alight Job:: call ( ' handler ' )-> date ( ' 2022-08-02 22:00 ' );Cada manipulador executa apenas um processo de cada vez e o tempo de execução máximo padrão de um processo é de 1 hora. Se o seu manipulador precisar de um tempo de execução mais longo, use timelimit ().
Alight Job:: call ( ' handler ' )-> hourly ()-> timeLimit ( 7200 ); // 7200 seconds O ALGAT fornece AlightApp::root() para padronizar o formato dos caminhos de arquivo no projeto.
// Suppose the absolute path of the project is /var/www/my_project/
Alight App:: root ( ' public/favicon.ico ' ); // /var/www/my_project/public/favicon.ico
// Of course, you can also use absolute path files with the first character '/'
Alight App:: root ( ' /var/data/config/web.php ' ); Os caminhos do arquivo na configuração são todos baseados no AlightApp::root() . Por exemplo:
Alight App:: start ([
' route ' => ' config/route/web.php ' , // /var/www/my_project/config/route/web.php
' job ' => ' config/job.php ' // /var/www/my_project/config/job.php
]); O ALGET fornece AlightResponse::api() para padronizar o formato da resposta da API.
HTTP 200 OK
{
" error " : 0 , // API error code
" message ": " OK ", // API status description
" data": {} // Object data
}Definição de status:
| Status HTTP | Erro da API | Descrição |
|---|---|---|
| 200 | 0 | OK |
| 200 | 1xxx | Erros de negócios gerais, exibem apenas mensagem para o usuário |
| 200 | 2xxx | Erros de negócios especiais, precisam definir a próxima ação para o usuário |
| 4xx | 4xx | Erros do cliente |
| 5xx | 5xx | Erros de servidor |
Por exemplo:
Alight Response:: api ( 0 , null , [ ' name ' => ' alight ' ]);
// Response:
// HTTP 200 OK
//
// {
// "error": 0,
// "message": "OK",
// "data": {
// "name": "alight"
// }
// }
Alight Response:: api ( 1001 , ' Invalid request parameter. ' );
// Response:
// HTTP 200 OK
//
// {
// "error": 1001,
// "message": "Invalid request parameter.",
// "data": {}
// }
Alight Response:: api ( 500 , ' Unable to connect database. ' );
// Response:
// HTTP 500 Internal Server Error
//
// {
// "error": 500,
// "message": "Unable to connect database.",
// "data": {}
// } ALGET fornece AlightResponse::render() para exibir um modelo de exibição Chame o método de renderização com o caminho do arquivo de modelo e dados do modelo opcional:
Arquivo: app/controller/páginas.php
namespace ctr ;
class Pages
{
public static function index ()
{
Alight Response:: render ( ' hello.php ' , [ ' name ' => ' Ben ' ]);
}
}Arquivo: app/view/hello.php
<h1>Hello, <?= $ name ?> !</h1>Arquivo: Config/Route/Web.php
Alight Route:: get ( ' / ' , [ ctr Pages::class, ' index ' ]);A saída da página inicial do projeto seria:
Hello, Ben!Existem também alguns ajudantes úteis colocados em diferentes namespaces. Clique no arquivo para obter detalhes:
| Espaço para nome | Arquivo |
|---|---|
| ALTIDO Solicitação | Request.php |
| ALTED Response | Response.php |
| Aumente utilitário | Utilitário.php |