npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

php-rest

v1.2.0

Published

PHP REST Framework

Downloads

2

Readme

php-rest

Simple object oriented PHP Framework to build JSON REST APIs.

It's 2017. Why PHP? Node.js is better!

  • Less dependencies. php-rest only requires PHP 5.3 features. No other external requirements.
  • Long Term Support. This software will work unchanged next year, and probably in the year 2027, too. We'll need something like a zombie apocalypse to make it obsolete.
  • Easy deployment. No need to setup process supervisors; your OS and Apache (or whatever HTTP server you use) already does that.
  • Less disk space. php-rest is about 836 kB. Our Node.js API framework takes freaking 182 MB.

It's a framework, not a library.

php-rest is intended to be a framework, not a library.

It's a tool you can use to easily build JSON based REST interfaces for your client side or backend projects, focus on your business logic and not to worry too much about the internal implementation details.

We use it to build backend APIs for our Node.js backends -- especially for our legacy projects.

About our terminology

Resource is any REST path which you can make HTTP requests with different methods.

Collection is a resource which lets you interact with multiple resources. These are normally other elements. It's like a database table.

Element is a resource which lets you interact with a single item. It's like a row in a database table.

Requirements

  • PHP 5.3. or newer

Optional features:

  • Web server software: Apache, Nginx, etc
  • Database Server: MySQL Server 5.0. or newer

Install

npm install --save php-rest

Using php-rest with Apache

Securing your API with HTTPS

Using HTTPS in the year 2017 is recommended, free and there isn't many good reasons not to use it. We recommend using Let's Encrypt. Apache has a good support for it, too.

Securing the project folder with .htaccess

You should start your project carefully securing your web folder with a .htaccess file(s). We have a sample file you can use as a starting point.

You can -- and probably should -- also use it to control who can make POST, PUT and DELETE requests. php-rest doesn't have any ACL support built-in.

Basic HTTP Authentication

Setup a password file at a path outside of webroot.

$ htpasswd -c /path/to/your/htusers foo
$ chmod 604 /path/to/your/htusers

Configure .htaccess file:

AuthName "REST API"
AuthType Basic
AuthUserFile **/path/to/your/htusers**
require valid-user

If you want to let people use GET, HEAD and OPTIONS; and only require authenticated users for other methods, you can limit it like this:

<LimitExcept GET OPTIONS HEAD>
Require valid-user
</LimitExcept>

Please note: You can also use MySQL instead of files with mod_authn_dbd.

Setup a front controller

Your REST backend will operate from a single front controller -- our example uses index.php.

Pass everything to the front controller

We'll use .htaccess to tell Apache to pass everything to our index.php:

AcceptPathInfo On
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]
Enable autoloader

Our framework has an interface to use __autoload(), which you can enable in your front controller:

function __autoload ($className) {
	return REST\Autoloader::load($className);
}

You should let it know where to find your business logic classes:

REST\addAutoloadPath(dirname(__FILE__) . '/src')
Enable database support

If you want to use our built-in MySQL database support, you need to configure it:

$db = new REST\Database(REST_HOSTNAME, REST_USERNAME, REST_PASSWORD, 
REST_DATABASE);
$db->charset(REST_CHARSET);
$db->setTablePrefix(REST_TABLE_PREFIX);
REST\setDatabase($db);
Extending from REST\DatabaseElement and REST\DatabaseCollection

These classes implement complete REST resources to use MySQL tables with GET, POST, PUT, and DELETE operations.

Minimal required setup is to call parent::setTableName('contact'); from the extending class to map it to specific MySQL table.

Of course, you can extend or overwrite any method.

Be careful! These elements do not have any ACL built-in. If you expose DatabaseElement -- or anything extended from it -- to the public, it will let delete and modify any row in your MySQL table.

Expose automatic API documentation with OPTIONS method

php-rest can automatically use PHP's ReflectionClass to read documentation from PHPdoc comments in your implementation and provide it to users as OPTIONS method. To enable this feature use REST\enableAutoOptions();.

Setup routes to resource implementations

Finally you'll need to map your routes to your business logic classes.

REST\run(array(
    "/" => "RootElement",
    "/contact" => "ContactCollection",
    "/contact/:contact_id" => "ContactElement"
));

Writing REST resources

You can extend from our abstract classes:

  • REST\Element, REST\Collection, or REST\Resource for non-database resources
  • REST\DatabaseElement, REST\DatabaseCollection, or REST\DatabaseResource for MySQL-based resources

When you want to overwrite a built-in method, you simply write a function with the name of the method:

/** The root resource for this REST service */
class RootElement extends REST\Element {
        /** Doesn't return anything useful yet. Simply a hello world. */
        function get (iRequest $request) {
                return array(
                        'hello' => 'world'
                );
        }
}

Note: You can also call parent::get($request) to use the parent implementation.

$request->getPath()

Returns the path of the request, like /Contact/1.

$request->getParams()

Returns the route parameters, like 1 for $params['contact_id'] if route had path like /Contact/:contact_id.

$request->getQuery()

Returns the request query params, like /[email protected] ==> $query['email'] ==> '[email protected]'.

$request->getInput()

Returns the parsed JSON body from the request.

Other methods

See Request.class.php for other public methods available.

Testing the API with curl

Source code for the example API at examples/.

$ curl -s -X OPTIONS https://www.example.com/api/|python -m json.tool
{
    "description": "The root resource for this REST service",
    "methods": [
        {
            "description": "Doesn't return anything useful yet. Simply a hello world.",
            "method": "get"
        },
        {
            "description": "Returns information for this REST resource",
            "method": "options"
        }
    ],
    "routes": [
        {
            "description": "Contact collection",
            "route": "/contact"
        },
        {
            "description": "Contact Element",
            "route": "/contact/:contact_id"
        }
    ]
}
$ curl https://www.example.com/api/
{"hello":"world"}
$ curl -s -X OPTIONS https://www.example.com/api/contact| python -m json.tool
{
    "description": "Contact collection",
    "methods": [
        {
            "description": "Returns all elements in the collection. You may use query params to limit matches.",
            "method": "get"
        },
        {
            "description": "Create a new element in the collection",
            "method": "post"
        },
        {
            "description": "Returns information for this REST resource",
            "method": "options"
        }
    ],
    "routes": [
        {
            "description": "Contact Element",
            "route": "/contact/:contact_id"
        }
    ]
}
$ curl -s -X GET https://www.example.com/api/contact| python -m json.tool
[
    {
        "contact_id": "5",
        "creation": "0000-00-00 00:00:00",
        "email": "",
        "name": "foo",
        "updated": "0000-00-00 00:00:00"
    },
    {
        "contact_id": "6",
        "creation": "0000-00-00 00:00:00",
        "email": "",
        "name": "bar",
        "updated": "0000-00-00 00:00:00"
    },
    {
        "contact_id": "7",
        "creation": "0000-00-00 00:00:00",
        "email": "",
        "name": "hello",
        "updated": "0000-00-00 00:00:00"
    }
]
$ curl -s -X POST -d '{"name":"Mr. Grey"}' https://www.example.com/api/contact| python -m json.tool
{
    "contact_id": "8",
    "creation": "0000-00-00 00:00:00",
    "email": "",
    "name": "Mr. Grey",
    "updated": "0000-00-00 00:00:00"
}
$ curl -s -X OPTIONS https://www.example.com/api/contact/8| python -m json.tool
{
    "description": "Contact Element",
    "methods": [
        {
            "description": "Returns the element",
            "method": "get"
        },
        {
            "description": "Removes the element",
            "method": "delete"
        },
        {
            "description": "Changes the element",
            "method": "post"
        },
        {
            "description": "Returns information for this REST resource",
            "method": "options"
        }
    ],
    "routes": []
}
$ curl -s -X POST -d '{"name":"Mr. Black"}' https://www.example.com/api/contact/8| python -m json.tool
{
    "contact_id": "8",
    "creation": "0000-00-00 00:00:00",
    "email": "",
    "name": "Mr. Black",
    "updated": "0000-00-00 00:00:00"
}
$ curl -s -X GET https://www.example.com/api/contact/8| python -m json.tool
{
    "contact_id": "8",
    "creation": "0000-00-00 00:00:00",
    "email": "",
    "name": "Mr. Black",
    "updated": "0000-00-00 00:00:00"
}
$ curl -s -X DELETE https://www.example.com/api/contact/8| python -m json.tool
{
    "deleted": "success",
    "id": "8"
}