PHPackages                             outlandishideas/php-crud-api-secure - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. outlandishideas/php-crud-api-secure

ActiveLibrary[API Development](/categories/api)

outlandishideas/php-crud-api-secure
===================================

Secure-by-default wrapper around mevdschee/php-crud-api.

v0.1.0(4y ago)139PHP

Since Jul 9Pushed 4y ago6 watchersCompare

[ Source](https://github.com/outlandishideas/php-crud-api-secure)[ Packagist](https://packagist.org/packages/outlandishideas/php-crud-api-secure)[ RSS](/packages/outlandishideas-php-crud-api-secure/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (1)Versions (2)Used By (0)

Secure PHP-CRUD-API
===================

[](#secure-php-crud-api)

A wrapper around [mevdschee/php-crud-api](https://github.com/mevdschee/php-crud-api) which makes it secure by default, by ensuring that the `authorization` middleware is enabled and has handlers for tables and columns.

Usage
-----

[](#usage)

This library is used in exactly the same way as [mevdschee/php-crud-api](https://github.com/mevdschee/php-crud-api)except that it will throw a `InvalidArgumentException` if the `authorization`, `authorization.tableHandler` and `authorization.tableHandler` middleware properties are not set in the API constructor.

### Using custom `tableHandler` and `columnHandler` functions:

[](#using-custom-tablehandler-and-columnhandler-functions)

Basic use case e.g. for Slim/Laravel app:

```
use Slim\App;
use Outlandish\PhpCrudApi\SecureConfig;
require 'vendor/autoload.php';

return function (App $app) {
    $app->get('/api[/{params:.*}]', function (
            Request $request,
            Response $response,
            array $args
        ) {
            $config = new SecureConfig([
                'middlewares' => 'pageLimits,authorization',
                'pageLimits.records' => 2,
                'authorization.tableHandler' => function ($operation, $tableName)  {
                    return $tableName != 'users'; //prevent CRUD api from performing any actions on the users table
                },
                'authorization.columnHandler' =>
                    function ($operation, $tableName, $columnName) {
                        if($tableName == 'participants'){
                            return $columnName != 'last_ip_address';
                        }
                        return false;
                    },
            ]);
            $api = new Api($config);
            $response = $api->handle($request);
            return $response;
        }
    );
};
```

### Using TablePermissions helper

[](#using-tablepermissions-helper)

The SecureConfig class can be passed an array of TablePermissions sub-classes to make it easier to explicitly define which columns from which tables can be operated on:

```
use Slim\App;
use Outlandish\PhpCrudApi\SecureConfig;
use Tqdev\PhpCrudApi\Api;
use Outlandish\PhpCrudApi\TablePermissions;

require 'vendor/autoload.php';

return function (App $app) {
    $app->get('/api[/{params:.*}]', function (
            Request $request,
            Response $response,
            array $args
        ) {
            class UsersTablePermissions extends TablePermissions
            {
                public function __construct()
                {
                    parent::__construct('users');
                    $this->allReadColumns = ["id", "display_name"];
                }

            }

            class PetsTablePermissions extends TablePermissions
            {
                public function __construct()
                {
                    parent::__construct('pets');
                    $this->allReadColumns = ["id", "name", "favourite_food", "species", "owner"];
                    $this->createColumns = ["name", "favourite_food", "species", "owner"];
                }
            }

            $tablePermissions = [
                PetsTablePermissions::getInstance(),
                UsersTablePermissions::getInstance()
            ];

            $config = new SecureConfig([
                'middlewares' => 'pageLimits',
                'pageLimits.records' => 2,
            ], $tablePermissions);

            $api = new Api($config);
            $response = $api->handle($request);
            return $response;
        }
    );
};
```

The `TablePermissions` sub-classes can set their column permissions with the `xyzColumns` properties below (as arrays of column names), and whether they can be deleted:

- `allReadColumns` (default for read/list)
- `allWriteColumns` (default for create/update/increment/delete)
- `readColumns`
- `listColumns`
- `createColumns`
- `updateColumns`
- `incrementColumns`
- `canDelete` (boolean)

We recommend handling authentication in your outer application rather than using the built-in middleware e.g.

```
class PetsTablePermissions extends TablePermissions
{
    public function __construct()
    {
        parent::__construct('pets');
        $this->allReadColumns = ["id", "name", "favourite_food", "species", "owner"];
        $this->createColumns = ["name", "favourite_food", "species", "owner"];
    }
}

class PetsTablePermissionsAuthenticatedUser extends PetsTablePermissions
{
    public function getUpdateColumns(){
        return $this->getReadColumns();
    }
}

if (Auth::check()) {
    // The user is logged in...
    $tablePermissions = [
        PetsTablePermissionsAuthenticatedUser::getInstance(),
    ];
}else{
    //it's an anonymous user
    $tablePermissions = [
        PetsTablePermissions::getInstance(),
    ];
}

```

###  Health Score

21

—

LowBetter than 18% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1774d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e1ae585faaa9c1bae546aa1e5a0a1fb55ca347fc09d19b7aeb57df808908c823?d=identicon)[outlandishideas](/maintainers/outlandishideas)

---

Top Contributors

[![rasmuswinter](https://avatars.githubusercontent.com/u/1754971?v=4)](https://github.com/rasmuswinter "rasmuswinter (1 commits)")

### Embed Badge

![Health badge](/badges/outlandishideas-php-crud-api-secure/health.svg)

```
[![Health](https://phpackages.com/badges/outlandishideas-php-crud-api-secure/health.svg)](https://phpackages.com/packages/outlandishideas-php-crud-api-secure)
```

###  Alternatives

[stripe/stripe-php

Stripe PHP Library

4.0k143.3M480](/packages/stripe-stripe-php)[twilio/sdk

A PHP wrapper for Twilio's API

1.6k92.9M272](/packages/twilio-sdk)[knplabs/github-api

GitHub API v3 client

2.2k15.8M187](/packages/knplabs-github-api)[facebook/php-business-sdk

PHP SDK for Facebook Business

90121.9M34](/packages/facebook-php-business-sdk)[meilisearch/meilisearch-php

PHP wrapper for the Meilisearch API

73813.7M114](/packages/meilisearch-meilisearch-php)[google/gax

Google API Core for PHP

263103.1M454](/packages/google-gax)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
