Code Monkey home page Code Monkey logo

siler's Introduction

⚠️ I'm afraid that I'm not being able to keep Siler up-to-date as it deserves, so it's repository has been archived.

As an alternative for Siler, something lightweight and simple that works as a library with Swoole out-of-the-box, I highly recommend Nano! Check it out: https://nano.hyperf.wiki/#/en/










Build codecov Psalm coverage Latest Stable Version Total Downloads License

Siler is a set of general purpose high-level abstractions aiming an API for declarative programming in PHP.

  • 💧 Files and functions as first-class citizens
  • 🔋 Zero dependency, everything is on top of PHP built-in functions
  • Blazing fast, no additional overhead - benchmark 1, benchmark 2 and benchmark 3

Use with Swoole

Flat files and plain-old PHP functions rocking on a production-grade, high-performance, scalable, concurrent and non-blocking HTTP server.

Read the tutorial.

Getting started

Installation

composer require leocavalcante/siler

That is it. Actually, Siler is a library, not a framework (maybe a micro-framework), the overall program flow of control is dictated by you. So, no hidden configs or predefined directory structures.

Hello, World!

use Siler\Functional as λ; // Just to be cool, don't use non-ASCII identifiers ;)
use Siler\Route;

Route\get('/', λ\puts('Hello, World!'));

Nothing more, nothing less. You don't need even tell Siler to run or something like that (puts works like a lazily evaluated echo).

JSON

use Siler\Route;
use Siler\Http\Response;

Route\get('/', fn() => Response\json(['message' => 'Hello, World!']));

The Response\json function will automatically add Content-type: application/json in the response headers.

Swoole

Siler provides first-class support for Swoole. You can regularly use Route, Request and Response modules for a Swoole HTTP server.

use Siler\Http\Response;
use Siler\Route;
use Siler\Swoole;

$handler = function () {
    Route\get('/', fn() => Response\json('Hello, World!'));
};

$port = 8000;
echo "Listening on port $port\n";
Swoole\http($handler, $port)->start();

GraphQL

Install peer-dependency:

composer require webonyx/graphql-php

Schema-first

type Query {
    hello: String
}
use Siler\Route;
use Siler\GraphQL;

$type_defs = file_get_contents(__DIR__ . '/schema.graphql');
$resolvers = [
    'Query' => [
        'hello' => fn ($root, $args, $context, $info) => 'Hello, World!'
    ]
];

$schema = GraphQL\schema($type_defs, $resolvers);

Route\post('/graphql', fn() => GraphQL\init($schema));

Code-first

Another peer-dependency:

composer require doctrine/annotations

Then:

/**
 * @\Siler\GraphQL\Annotation\ObjectType()
 */
final class Query
{
    /**
     * @\Siler\GraphQL\Annotation\Field()
     */
    public static function hello($root, $args, $context, $info): string
    {
        return 'Hello, World!';
    }
}
use Siler\GraphQL;
use Siler\Route;

$schema = GraphQL\annotated([Query::class]);

Route\post('/graphql', fn() => GraphQL\init($schema));

Object type name will be guessed from class name, same for field name, and it's return type (i.e.: PHP string scalar === GraphQL String scalar).

What is next?

License

License

siler's People

Contributors

arysom avatar carusogabriel avatar cmdlucas avatar compwright avatar deadphoenix8091 avatar dependabot-preview[bot] avatar dependabot[bot] avatar eaverdeja avatar eghojansu avatar gitter-badger avatar glensc avatar gskierk avatar hadron43 avatar juliend2 avatar kodiakhq[bot] avatar leocavalcante avatar lex111 avatar marcokuoni avatar michaelphipps avatar muglug avatar petemcfarlane avatar pokemaobr avatar quadrifolia avatar r-j avatar sauliusugintas avatar segy avatar spawnia avatar symm avatar trollboy avatar userlond avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

siler's Issues

Typo on method doc for recommended_locale

The line 239 have $_SESSION['lang] where it should be $_SESSION['lang'].

I'd like to avoid opening a PR just for that, could you correct that typo ?

Also, switching '' with "" line 248, so Github syntax coloration is happy !

GraphQL\GraphQL::execute is deprecated

PHP Deprecated: GraphQL\GraphQL::execute is deprecated, use GraphQL::executeQuery()->toArray() as a quick replacement in /var/www/html/siler-graphql/vendor/webonyx/graphql-php/src/GraphQL.php on line 187

Need to change on https://github.com/leocavalcante/siler/blob/master/src/Graphql/Graphql.php#L91

return GraphQL::execute(
        $schema,
        $query,
        $rootValue,
        $context,
        $variables,
        $operation
    );

to

return GraphQL::executeQuery(
        $schema,
        $query,
        $rootValue,
        $context,
        $variables,
        $operation
    );

[Insight] Text files should end with a newline character - in docs/concepts.md, line 41

in docs/concepts.md, line 41

This file ends with no newline character. It won't render properly on a terminal, and it's considered a bad practice. Add a simple line feed as the last character to fix it.

* [Object-Oriented Programming is Bad - Brian Will](https://www.youtube.com/watch?v=QM1iUe6IofM)
* [Stop Writing Classes - Jack Diederich](https://www.youtube.com/watch?v=o9pEzgHorH0)
* [Advanced OOP in Elixir - Wojtek Mach](https://www.youtube.com/watch?v=5EtV2JUU0Z4) *(spoiler - is an ironic talk)*
* [Was object-oriented programming a failure? - Wouter van Oortmerssen](https://www.quora.com/Was-object-oriented-programming-a-failure/answer/Wouter-van-Oortmerssen)

Thank you.

Posted from SensioLabsInsight

Access GET/POST params in Swoole

Hi Leo,

Yesterday, I tried to use Siler with Swoole. It's great. Alas, I can't access GET or POST params when I used files base route.

index.php

Route\get('/3', 'controller.php', Swoole\cast($req))

controller.php

var_dump($params) // array for route [0] => 3
var_dump($req, $res) // error
var_dump(\Siler\Http\Request\get()) // null

Is there any way to access it?

Make siler more tiny

We can split siler plugins into its own repository. I know it's sound silly to make repo for tiny source code, but it will make dependency more implicit.
As example, if we require twig functionality, we simply require siler/twig and composer will do the job to install twig/twig too.

[Insight] Object parameters should be type hinted - in src/Graphql/Graphql.php, line 82

in src/Graphql/Graphql.php, line 82

The parameter info, which is an object, should be typehinted.

 *
 * @param $resolvers
 */
function resolvers(array $resolvers)
{
    Executor::setDefaultFieldResolver(function ($source, $args, $context, $info) use ($resolvers) {
        if (array_key_exists($info->parentType->name, $resolvers)) {
            $subject = $resolvers[$info->parentType->name];

            if (is_callable($subject)) {
                $subject = $subject($source, $args, $context, $info);

Posted from SensioLabsInsight

GraphQL websocket security

Hi,

I am curious how we can implement authentication when subscribing on GraphQL, with the example, anyone who knows the roomName can subscribe to the websocket endpoint.

λ

More functional abstractions!

  • Callable to filter by is_null and/or empty
  • Partial-application

Strings

Functions to perform on String operations

  • Slugify
  • Cross-platform break-lines

Apache virtualhost integration configuration

For development, the composer serve script works well, but for production, it's better to run the PHP server with something like a NGINX server or an Apache server.

I looked a it in the library's source code but didn't find any clue on how to make a valid Apache2 configuration to use the index.php entry point file (with for example a code like below).
Could you make an example configuration or a small documentation page ?

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);

// Requiring composer deps
require_once ('./vendor/autoload.php');

use Siler\Route;
use Siler\Functional as f;

Route\get('/m', f\puts('Meow'));
Route\get('/v', f\puts('Time is '.time()));

GraphQL example

Hello,

I have followed graphQL example from docs https://siler.leocavalcante.com/graphql/ but it doesnt work to me. When I run GraphiQl with:

query {
  rooms {
    id
    name
  }
}

I get following result:

{
  "errors": [
    {
      "message": "Syntax Error GraphQL (1:1) Unexpected <EOF>\n\n1: \n   ^\n",
      "category": "graphql",
      "locations": [
        {
          "line": 1,
          "column": 1
        }
      ]
    }
  ]
}

I have installed all the dependencies (composer.json).

{
  "require": {
    "leocavalcante/siler": "dev-master",
    "webonyx/graphql-php": "^0.11.5",
    "gabordemooij/redbean": "^5.0"
  }
}

There isnt any error in apache/error log. What could be causing the problem?

Callable stops execution of router

Calling a non-static method using the default callable implementation always causes the constructors to be called, which is undesirable. See in the example below even if you call the / route, the execution will be stopped as the constructor in test will be called.

class TestController {
    function __construct() {
         if (has_access() == false){
             die('No Access');
         }
    }
    function page() {
        return "Page A";
    }
}
Route\get('/user', [(new TestController), "page"]);
Route\get('/', function(){
    return "Home";   
});

I would suggest a workaround for calling non-static methods

Route\get('/user', "TestController@page");

Add raw body storing

When using siler for a website, and assuming the request is only sent by a form using either application/x-www-form-urlencoded or multipart/form-data, PHP parses the request body and populates the $_POST variable with parse results.

If it doesn't recognise the Content-Type of the request or if it's incorrectly set, PHP will fail to parse without a warning and will only give an empty $_POST.

Such behaviour would be expected when using Siler as a backend API, receiving and sending back JSON (e.g. with the JSONP request format).

For that, the trick is to read from php://input but that can only be done 1 time (source). For now, the Request::raw method does the trick, but only one time.

I'll work on the Request.php file to add lazy retrieving/global storing to avoid data loss when reading multiple times.

Unable to get the PUT param

Hi, either in Siler\Request or Siler\Diactoros it is possible to get the URI param (using Route\resource), I just tried THE PUT verb : PUT | /users/{id} | update.php
Anyway i did that :

$id = explode('/', \Siler\Diactoros\request()->getServerParams()['REQUEST_URI'])[2];

Is there an other possibility ?
Thanx, Great work by the way.

EDIT:
I just figured out :
I put $id = array_get($params, 'id') in any controller and it works, i don't where this "global variable" come from but it works.

Fresh Install getting error

I have installed this in a subfolder and I am getting this error

Parse error: syntax error, unexpected '(' in /Users/XYZ/Work/htdocs/project/vendor/leocavalcante/siler/src/Functional/Functional.php on line 113

This error comes when I access site like http://localhost/project/

But when I do composer serve site works fine over http://localhost:8000/

I have to put this on a shared hosting where I can not run composer serve

Logging - questions

Everytime I call any Siler endpoint, it got logged to console like this:
[Sat Jan 12 22:49:53 2019] 127.0.0.1:54408 [200]: /healthCheck

I'd like to understand where it is comming from, is there any way to turn it off, change formatting or so? Is there an implementation of logging interface somewhere in Siler, can we use it too?

Notes:

  1. I'm using compose serve to serve.
  2. Pls excuse me if these questions are dumb, lost contact with PHP decade ago 😉

when can we expect a release?

I like your project and approach to design.
when can we expect a release?
it would be good to introduce boilrplate to framework's recommended directory structure (like lumen or so)..

Dropping Ratchet Support

Planning to drop Ratchet support in favor of explicit using Thruway instead, which is already simple to use and creating a wrapper to it is unnecessary.

[Insight] Unused method, property, variable or parameter - in src/Route/Route.php, line 141

in src/Route/Route.php, line 141

This ext local variable is declared but never used. You should remove it.

    $filename = str_replace('\\', '/', $filename);
    $filename = trim($filename, '/');
    $filename = str_replace('/', '.', $filename);

    $tokens = explode('.', $filename);
    $ext = array_pop($tokens);
    $method = array_pop($tokens);
    $path = implode('/', $tokens);
    $path = '/'.trim(str_replace('index', '', $path), '/');

    return [$method, $path];

Posted from SensioLabsInsight

Cache repetitive function result

Hi, can we make siler cache repetitive function result ?
Example: Http\path always get called when use Route\route.
Imagine if we use Route\files and there is hundreds of file inside the $basePath.

Siler is fast, and I think we can make it faster a bit. :)

Request\json crashes on empty request body

If someone tries to do a Siler\Http\Request\json() when the request body is empty, the json_decode will fail (and return null), and the array type enforcing will fail, thus throwing a TypeError.

An example message is:

Fatal error: Uncaught TypeError: Return value of Siler\Http\Request\json() must be of the type array, null returned

Any route

Can we have a helper method called any:

Route\any('/path', <handler>);

Route parameters into controller file, object/method

Is there a way to pass request and params to object/method?

As a method call using PHP's array notation:

use Siler\Route;

class Hello {
  public function method() {
    echo 'Hello Array Notation';
  }
}

$obj = new Hello();
Route\post('/', [$obj, 'method']);

What I want to do:

Route\post('/blog/{id}', ['App\Controllers\Blog', 'update']);

App\Controllers\Blog.php

<?php
namespace App\Controllers;

class Blog
{
    public function update(Request $request)
    {
        echo $request->id;
    }
}

I mean, there is a way to inject params into method or any other way to access route params inside controller/method function?

BTW, shining job 👏
Congratz and thank you

Test Siler\Ratchet\init

There is no tests for Siler\Ratchet\init, weirdly is it passing by Codecov, but not by PHP Unit coverage report.

Ressource show.php will be called for /create

Hello,
In a route resource, the path "/create" will also call show.php because it will match "/{id}".
You have to either "exit();" in create.php, or "if ("create" == $params['id']) { return; }" in show.php.
Any idea to make it work without the workarouds ?

Define 404 for incorrect route

Hello,

Can you help, please...
In case request undefined route - Siler response empty body with 200 code.

But how to define 404 error for incorrect/undefined route?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.