Download the PHP package neoan.io/core without Composer
On this page you can find all versions of the php package neoan.io/core. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download neoan.io/core
More information about neoan.io/core
Files in neoan.io/core
Informations about the package core
neoan.io Lenkrad core
Online Documentation @ lenkrad.neoan3.rocks
This is a core rewrite of neoan and not (yet) meant for production. Using modern PHP, we believe it's possible to create easy & static internal APIs without the usual problems regarding mocking & injection and testability.
It's modern!
At a glance:
As you can see, a lot of overhead can be omitted while maintaining an approachable style.
You will need PHP 8.1 & composer2 to run this
- Why yet another framework?
- Getting Started
- Setup
- Routing
-
- Methods
-
- Endpoint Parameters
-
- Routable classes
-
- Middleware / Chaining
-
- Response Handling
-
- Injection
-
- Views
-
- Using Attributes
- Inputs & Outputs
- Templating
-
- HTML skeleton
-
- Templating basics
- Events
- Dynamic Store
- Models
-
- Database Setup
-
- Model basics
-
-
- Creation
-
-
-
- Retrieve & update
-
-
-
- Collections
-
-
-
- Pagination
-
- Migrations
- Testing
- Contribution
Why?
PHP has come a long way. Most frameworks focus on backward-compatability to allow existing code-bases to securely update framework security patches without breaking changes. However, if you are starting a project, why would you forgo the power of modern PHP?
Do you realize what a framework could do for you, if it utilized
- attributes
- enums
- intersection types
- match expressions
- named parameters
- readonly properties
- union types
- ...
Execution time would be way faster, but could it make your life easier?
Getting Started
composer require neoan.io/core
index.php
php -S localhost:8080 index.php
Setup
soon: working on create-project scripts
This readme will guide you to an understanding of your personal needs. For the impatient - and as a cheat sheet, find a basic setup script:
composer require neoan.io/core
composer require neoan.io/legacy-db-adapter
(optional: You can also use Neoan\Database\SqLiteAdapter while developing)
You are free to chose your folder structure. For now, we will assume the following structure:
Utilizing the following PSR namespace definition in our composer.json
:
/cli
/public/index.php
/src/Routes/HtmlRoutes.php
/src/Config/Setup.php
Routing
Registering routes is easy and intuitive:
HTTP-Methods
Simply use the method keyword to register a route for shorthand syntax.
the following methods are currently implemented:
- get
- post
- put
- patch
- delete
example:
Endpoint-Parameters
Endpoints can handle parameters with the ":"-notation like so:
This will match a call to "/users/12" and expose the value (here "12") to the Request (see Handling inputs & outputs)
Routables
You can chain as many classes as you wish into the route (middleware). Classes must implement the Routable Interface and an invoke function and return one of the following types:
- array
- string
- Neoan\Model\Collection
- Models | Neoan\Model\Model
example:
Chained routes
The return value of a previously executed class is exposed to the next classes.
Let's assume the following middleware:
With the following route:
In this scenario, the returned array gets passed into our controller-class, overwriting potentially previously set values of "auth". Our controller never gets executed if the authorization wasn't successful, as the error "Unauthorized" terminates execution. If we are authorized, however, we now have "auth" available to us:
Response handler
By default Routes are resolved as having the built-in JSON response. However, you either change the default behavior:
Or use a route-specific output handler:
Inject
To make life easy where it can be, you can directly inject values into a route:
This will provide values to all listed classes and can often substitute middleware.
Views
The default templating engine used is "neoan3-apps/template", a battle-tested solution. To set up a location for your views, first define the general directory. E.g.
Then, you can use relative paths when routing:
Learn more about the neoan3-apps/template template engine
Routing Attributes
You can register routes using attributes as well. IN order to do so, two prerequisites have to be met:
- Register namespace(s) via AttributeRouting
- Add appropriate attributes to routable classes
This will register routes in a "ruby"-like manner instead of having to define routes manually. the following attributes are at your disposal:
- Web(string $route, string $viewTemplate, ...$middlewareClasses)
- Get(string $route, ...$middlewareClasses)
- Post(string $route, ...$middlewareClasses)
- Put(string $route, ...$middlewareClasses)
- Patch(string $route, ...$middlewareClasses)
- Delete(string $route, ...$middlewareClasses)
Handling inputs & outputs
Input handling is very intuitive. The "Request" class carries (among others) the following methods for your convenience:
- getInput(string $name): string
- getInputs(): array
- getQuery(string $name): string
- getQueries(): array
- getParameter(string $name): string
- getParameters(): array
UserShowController:
UserCreateController:
Templating
The default templating engine is attached to the default Renderer. Both can be exchanged, but for now let's focus on the built-in tooling.
We will only cover basics of the templating engine here, please refer to the repository of neoan3-apps/template for deeper understanding.
To set your default template path, use
Note: By default, the template engine uses project path. Using "setTemplatePath" overwrites that value. This means you have to declare the path relative to your project-root. Let's look at a setup example:
In the above scenario, setting our template path would be:
Skeleton
To simplify the most common scenario, the Renderer uses a "skeleton" to surround your component specific views. This skeleton can be seen as a shell or frame and often includes header & footer.
example:
We can now set this file to be our skeleton:
To complete the example, we'll create a view & route
The output when visiting /test/Eve would be
Templating basics
You have already seen the general markup with curly brackets {{var}}
.
A few pointers for common tasks, assuming the following PHP output
Nested variables
Iterations
Conditionals
Events
Events are a useful tool to control and abstract logic and offer a clean way of adding custom functionality. The core itself uses system events (GenericEvents) for debugging & testing, so listening or dispatching them does not yield side effects during runtime:
- DATABASE_ADAPTER_CONNECTED
- BEFORE_DATABASE_TRANSACTION
- AFTER_DATABASE_TRANSACTION
- BEFORE_RENDERING
- REQUEST_HANDLER_INITIALIZED
- REQUEST_HEADERS_SET
- REQUEST_INPUT_PARSED
- ROUTE_HANDLER_INITIALIZED
- ROUTE_REGISTERED
- RESPONSE_HANDLER_SET
- BEFORE_RESPONSE
- ROUTE_INJECTION
- BEFORE_ROUTABLE_EXECUTION
We use common terminology for the methods:
In addition to this functionality, you can listen to notifications fired by Routable & Model classes with
Event::subscribeToClass(string $className, callable $closureOrInvokable)
.
If you want to extend what classes you can listen to, simply implement Neoan\Event\Listenable in this way:
This is useful especially when chaining middleware and you want to react to outcomes that haven't happened yet.
Dynamic Store
The static store object is an integral part of the design decision. It functions as a "free-for-all" global memory used by the core itself and is fully exposed to user land. One of it's core competencies is the ability to use not yet initiated values without the syntactical overhead of event listeners.
In practice, this allows us to use variables that will be set eventually to be used in code, creating a promise-like structure without the requirement for actual asynchronous behavior.
Models
Modern MVC frameworks use object-relational mapping (ORM) to interact with data. While neoan.io lenkrad is no different, the possibilities of PHP have finally grown to the point where manual mappings of database-structure and runtime-object are no longer required if done correctly.
Database setup
This package does not yet ship with a default database adapter. For now, mysql & mariadb connectivity is created with the package neoan.io/legacy-db-adapter.
composer require neoan.io/legacy-db-adapter
Please refer to neoan3-apps/db for setup instructions and deeper understanding.
Model basics
At its core, a model is a single object that inherits the capabilities of the core model class.
example:
Just to be complete, this is how our ReviewModel would look like:
We are going to jump ahead here to actually make this example work:
php cli migrate:mysql App\Model\MovieModel
&
php cli migrate:mysql App\Model\ReviewModel
Creation
To create a new record you simply store an instance of a model.
About security: The combination of using prepared statements as well as assignment guards makes it secure (and convenient) to handle user input:
Model classes automatically which modes between existing and new entries. If you run into edge-cases, you can change the mode manually:
Retrieve & update
If you want to modify existing records, we want to get the existing record first:
Collections
Collections are a useful tool to manage multiple instances at once. Whenever you are retrieving more than one record, a Collection will be returned.
Collections are iterable and have the following additional capabilities:
Pagination
A common task is the necessity to paginate collections that would otherwise be too big. You can conveniently paginate each model:
The response of a pagination is an array like this:
Migrations
You might have noticed that there aren't any files handling migrations.
Instead, the cli compares the existing table with your model definition and makes
updates accordingly. However, what happens on the database does not have to be invisible to you.
The basic command migrate:model $dialect $modelQualifiedName
has additional options:
- with-copy (c)
- output-folder (o)
example:
This will output the database operations to a sql-file (in our case /src/migrations) and create a copy of the table named "movie_backup" before any altering commands are executed.
NOTE: the output folder must exist under the NeoanApp->appPath
You can also migrate all models within any defined auto-loaded namespace at once. This is particularly useful when installing an app or when collaborating:
Supported dialects
Currently, the following dialects are supported out of the box
- mysql
- sqlite
However, it is easy to create your own commands: see cli
Testing
The core itself uses PHPunit & CI with a high test-coverage. In the future we want to provide tooling for application testing as well. For now, please implement your own testing methodologies.
CLI
The cli is based on symfony/console wrapped in a container which makes neoan.io lenkrad available to scripts.
As such, you can add your own symfony console commands to the suggested file cli
as you normally would:
To see available commands:
Contribution
For now we are looking for feedback only as marketplace rules and fundamentals aren't written in stone yet. However, please star, commend issue tickets to help us build out and improve this lightweight solution.
All versions of core with dependencies
neoan3-apps/template Version ^2
neoan3-apps/db Version ^0.3
vlucas/phpdotenv Version ^5.4
symfony/console Version ^6.1
ext-pdo Version *
neoan.io/legacy-db-adapter Version ^1.0
ext-openssl Version *
composer/composer Version ^2
ramsey/uuid Version ^4.6
monolog/monolog Version ^3.7.0