PHP Router in 140 Characters

This is a dimple(damn simple) URL routing script for PHP which is written in just 140 characters of code, so it fits within a tweet.

Its NOT a good router at all, don’t use it in a real application, its not exception handled either. I did it just for fun and to demonstrate the simplicity

So here’s the router code, and that’s all (seriously).

class R{
function a($r,callable $c){$this->r[$r]=$c;}
function e(){$s=$_SERVER;$i='PATH_INFO';$p=isset($s[$i])?$s[$i]:'/';$this->r[$p]();}
}

Fork on GitHub.

Usage

Create a file index.php in your server root and try this code

<?php
// The router code
class R{
function a($r,callable $c){$this->r[$r]=$c;}
function e(){$s=$_SERVER;$i='PATH_INFO';$p=isset($s[$i])?$s[$i]:'/';$this->r[$p]();}
}
//


// Create 
$router = new R();

// Add a route with a callback function
$router->a('/a', 'callbackFunction');

// Add a route with a closure
$router->a('/b', function(){
    echo 'Hello B';
});

// Add homepage route
$router->a('/', function(){
	echo 'Hello World';
});

// Add route with class method
$router->a('/c', [new Foo, 'bar']);
// Add multiple slashed route with class method
$router->a('/c/d', [new Foo, 'bar']);

// Execute the route
$router->e();

// Callback handlers
function callbackFunction(){
	echo 'Hello A';
}

class Foo{
	function bar(){
		echo 'Hello Bar';
	}
}

Now visit your server root http://localhost/index.php, http://localhost/index.php/a, http://localhost/index.php/b, http://localhost/index.php/c and http://localhost/index.php/c/d.

Or you may run built-in PHP server from the command line (in the same dir)

[code]
php -S localhost:8081
[/code]

and visit http://localhost:8081/index.php.

Runs on 5.4+. 140 chars idea is inspired by Fabien Potencier’s Twittee.

GetSetGo – Dynamic Setter Getter Library for PHP

Build Status

GetSetGo is a dynamic setter-getter library for PHP 5.4+. Its developed by me and Sheikh Heera, and yes, its well unit tested.

You can use methods like setFoo('bar') and getFoo(), which you DON’T have to create (in your class). GetSetGo will make these methods work for you automatically as long as you have a $foo property in your class.

It makes use of Traits, so using it is super simple, you don’t have to extend any class, as you can extend a single class only, we don’t force you to use ours.
You can restrict to only getter only or you can specify a Type for property using annotations.

View on GitHubPackagist

Installation

GetSetGo uses Composer to make hassles Go.

Learn to use composer and add this to require (in your composer.json):

[code]
"usmanhalalit/get-set-go": "1.*@dev"
[/code]

Usage

Just add this in your classes:

use \GetSetGo\SetterGetter;

Example:

Class MyClass{
    use \GetSetGo\SetterGetter;

    protected $foo;
}

Now use it as
$myClass = new MyClass;

$myClass->setFoo('bar');
echo $myClass->getFoo();

That’s basically it.

Restrict Getter or Setter or Both

You can use annotation in you class property if you want to disable setter, getter or both using @setter and @getter annotation variables.

/**
 * We can't use setSomeProperty() anymore.
 *
 * @var
 * @setter false
 */
protected $someProperty;


/**
 * We can't use getSomeProperty() anymore.
 *
 * @var \stdClass
 * @getter false
 */
protected $someProperty;


/**
 * We can't use setSomeProperty() or getSomeProperty().
 *
 * @getter false
 * @setter false
 */
protected $someProperty;

Force a Type or Class

You can specify a type for the property using @var annotation variable, so setter will take only a value of this type, else it will throw an exception. The code below will work similar as public function setSomeProperty(stdClass $value){}

/**
 * Should be an instance of stdClass only.
 *
 * @var \stdClass
 */
protected $shouldBeStdClass;


/**
 * Should be an array only.
 *
 * @var Array
 */
protected $shouldBeArray;


/**
 * Should be a string only
 *
 * @var String
 */
protected $shouldBeString;


/**
 * Should be a number only.
 *
 * @var Number
 */
protected $shouldBeNumber;


/**
 * Should be an object only.
 *
 * @var Object
 */
protected $shouldBeObject;

Notes

GetSetGo assumes that you use proper camelCase. So name your properties like $pdoInstance (not $PDOInstance) and call setPdoInstance() method.

Laravel 4 Uses Lots of Static, Not True.

Most of the time developers blame Laravel for using too much static. This claim is not true in case of Laravel 4, lets dig in and discuss why and how.

What is static?

In PHP you call it like this Class::$property.

As the name suggests, it preserves the state. Static variables preserve their values across the lifetime of the running application(in our case request). In a class if a static property is declared it becomes the property of the CLASS itself, NOT the property of the instance(s) of the class.

Why is static considered bad?

Well, there are debates. One of main reasons is, you can’t (quite) Mock a static variable or method as its difficult to override statics because the state is preserved and no object/instance is used. This makes it really difficult to Test(Unit Test) an application as Mocking is a must needed thing to unit-test an application fully.

When you start unit-testing your application then you will realize why static dependencies are so bad. It becomes quite impossible to replace implementations during testing. So you end up creating lots of hacks just for maintaining testability.

How does Laravel static work?

Laravel 4 doesn’t actually use static rather it mimics the static calling behavior. When you call a static method, actually much more things happen behind the scene than it appears. Lets go through the life cycle of a static call.

As an example we’re calling View::make('hello').
You will see literally there is no class View under the \ namespace. Rather Laravel uses aliases, so when you look at app/config/app.php, you will see View is just an alias of Illuminate\Support\Facades\View. So you’re actually calling:

Illuminate\Support\Facades\View::make('hello');

When we go to Illuminate\Support\Facades\View under (vendor/laravel/framework/src) we see just this code:

class View extends Facade {

	/**
	 * Get the registered name of the component.
	 *
	 * @return string
	 */
	protected static function getFacadeAccessor() { return 'view'; }

}

It extends the base Facade class, and in both classes there is no static method make(). The magic happens on the base Facade class, where there is a magic method __callStatic. This is called PHP Overloading, whenever you call a static method and this class doesn’t have that method then __callStatic is called(like a 404 page) with the called method name(‘make’) as the first parameter and the called parameters’ array as second parameter(array(‘hello’)).

What __callStatic does basically here, it calls the IoC Container binding with the name ‘view’ and calls the (non-static)method (‘make’) within it. What IoC Container contains, a pure instance of the original View class, in an object oriented way (not a class oriented way). So we can re-write the View::make('hello') as

$app->make('view')->make('hello')

Conclusion

Now we know Laravel makes it super easy to call methods which makes it look like static but actually its not, so we can easily mock the original View class and get our tests pass. Using these facades for static call is just a way to access Laravel classes, you can write your entire app without using these facades(static calls). Do you find anything incorrect, do you have something better to share? Please write in the comments.

Filter Eloquent Results by Overriding in Laravel (v 3 & 4)

Now Laravel has this feature built-in

What is Eloquent?

Eloquent has been a really popular ORM in the PHP community lately, it was initially built for Laravel framework only. But since Laravel 4 all the components including Eloquent are built as Packages which may depend on other packages. These packages can be installed through Composer and can be browsed on Packagist. So what’s cool? Think of people out there who either don’t use Laravel or don’t use any framework at all. They might roll their own code or just whack a bunch of packages (like Eloquent) from Packagist together. If you use Laravel you can install and use various Symfony components/packages or any other package like Hybrid Auth with a simple command.

Lets Code

When we run queries from Eloquent sometimes we need to filter results from the very beginning. I will do it with an example to make understanding easy, but you are free to apply it however you want.

So sometimes we have users in database and admin can ban few of them for whatever reason, then lets assume you set users table’s status=0 for these users, now you have to filter (status=1) everywhere to restrict banned users from appearing (like login, profile view, edit send message etc.), and this can be real pain and not-a-cool-way as well. What if we can filter banned users right from our Eloquent model each time, so however we call users, User::all() or User::find(2) or User::where('username', 'like', '%usman%')->get() or whatever, banned users won’t appear in the results as long as you use this Eloquent model? Pretty cool yeah! Lets do it:

You have a User model which extends Eloquent, put this code into that class:

    /**
     * Overrides (Laravel or)Illuminate\Database\Eloquent\Model 's query()
     *
     * @return mixed
     */
    public function newQuery($excludeDeleted = true)
    {
        $query = parent::newQuery($excludeDeleted);
        // A much better way to restrict access to all banned (status = 0) users
        // from beginning (including search, profile views etc.), disabling them
        // to access anything even if they were logged in previously.

        $query-&gt;where('status', '!=', 0);
        return $query;
    }

That’s pretty much it, now you will never see banned users 🙂

What if We Need to Get Banned Users?

Well, above code will basically serve the purpose, but what if we need to get banned users (too) sometimes, like in the admin panel or if we want to check why the login was denied, is it because his status=0? Well you can do it. After this feature, your overall class will look as follows:

class User extends Eloquent
{
    protected static $_allowBannedUsers = false;

    /**
     * Overrides (Laravel or)Illuminate\Database\Eloquent\Model 's query()
     *
     * @return mixed
     */
    public function newQuery()
    {
        $query = parent::newQuery();
        // A much better way to restrict access to all banned (status = 0) users
        // from beginning (including search, profile views etc.), disabling them
        // to access anything even if they were logged in previously.

        if(! static::$_allowBannedUsers)
        {
            $query-&gt;where('status', '!=', 0);
        }else{
            // If its true then make it false so that banned users don't appear in next calls.
            static::$_allowBannedUsers = false;
        }
        return $query;
    }

    /**
     * @return User
     */
    public static function allowBannedUsers()
    {
        static::$_allowBannedUsers = true;
        return new static;
    }
}

The above code seems self explanatory. Now you can get banned users if needed just by chaining allowBannedUsers() method, for example:
User::allowBannedUsers()->all() or User::allowBannedUsers()->find(2) or User::allowBannedUsers()->where('username', 'like', '%usman%')->get()

Laravel 3?

If you are using Laravel 3 then please change the name of the method newQuery() to query() (without any parameters) like:

public function query()

and

$query = parent::query();

If you like this tirck then you may like my new project Pixie Database Query Builder. It has Query Events built-in for doing such tricks.

Conclusion

Feel free to do whatever you need instead of just restricting banned users. Also I would like to hear any better solution or if you think this solution has any pitfall. How do you solve this problem? Please comment below.

I will be glad if this helps you, please share this tutorial if you think it would help others.

Stay tuned for more Laravel tutorials.

XSS Filter in Laravel Framework

If you are connected with the PHP development world then you must have heard the name Laravel and you know what it is. If you don’t know, Laravel is a modern PHP framework which utilizes modern PHP features and uses some of the existing frameworks’ components to truly awesomify PHP development.

Back in 2012 I gave Laravel a try out of curiosity and I was amazed by the flexibility, features and easiness it offers. I took another decison to learn it and then to use it on my new projects. Now I have learned Laravel and developed projects using it. I am not leaving development with CodeIgniter, just using both, in fact my current long term work Vegan Cuts is based on CodeIgniter.

One thing you might miss on Laravel is XSS (Cross-site Scripting) Cleaning/Filtering method for inputs, specially if you have come from CodeIgniter background. I truly understand that its better to do it on output and Laravel has a method HTML::entities with a handy shorthand e() (removed in Laravel 4) which converts HTML characters into entities, its almost PHP’s native function htmlentities() (also Blades’s syntax can escape data). But I do prefer filtering/sanitizing both inputs and outputs, I don’t see any reason to allow saving HTML tags in database, also you may accidentally forget to use htmlentities() on your output and it puts you on risk. So I prefer to strip all the tags from input globally and then for a better security use htmlentities() on output.

Here we go …

So how can we do XSS Clean on all the inputs in Laravel? I have a solution for you, if you don’t have a library to write common methods you may need frequently then I ask you to create a new library Common in application/library (in case of Laravel 4, create a Common model in app/models). Put this two methods in your Common library/model:

    /*
     * Method to strip tags globally.
     */
    public static function globalXssClean()
    {
        // Recursive cleaning for array [] inputs, not just strings.
        $sanitized = static::arrayStripTags(Input::get());
        Input::merge($sanitized);
    }

    public static function arrayStripTags($array)
    {
        $result = array();

        foreach ($array as $key => $value) {
            // Don't allow tags on key either, maybe useful for dynamic forms.
            $key = strip_tags($key);

            // If the value is an array, we will just recurse back into the
            // function to keep stripping the tags out of the array,
            // otherwise we will set the stripped value.
            if (is_array($value)) {
                $result[$key] = static::arrayStripTags($value);
            } else {
                // I am using strip_tags(), you may use htmlentities(),
                // also I am doing trim() here, you may remove it, if you wish.
                $result[$key] = trim(strip_tags($value));
            }
        }

        return $result;
    }

Then put this code in the beginning of your before filter (in application/routes.php, in Laravel 4 it should be in app/filters.php):

    // Our own method to defend XSS attacks globally.
    Common::globalXssClean();

Note: I am using strip_tags(), you may use htmlentities(), also I am doing global trimming here, you may remove it, if you wish. Stripping tags will disable your users to store any HTML tags, if you need your user to write WYSIWYG content then I suggest you to use Markdown and convert it to HTML while doing output, it is the secured way, there are many libraries to help you.

More Laravel tutorials are coming, stay tuned 🙂