1. PHP array filtering with anonymous functions

    Here's a technique from the blog software I wrote for this site. This software is structured in 3 separated layers, implemented in different classes:

    1. The user interface (UI) that displays blog posts in different pages.
    2. A service that exposes business methods to get the posts.
    3. A data access object (DAO) that interacts with the database to retrieve, and store, post data.

    The blog has 4 pages: my articles, text links, image thumbnails and videos. And there are RSS feeds exposing the same information. The UI classes use specific service methods to get the required posts for each page or feed.

    The service has methods like getLatestArticles(), getLatestLinks() etc.

    These methods all have the same structure:

    1. get the posts from the database
    2. filter the posts
    3. return the posts that match

    The code I wrote has the criteria declared in variables in the form of anonymous functions:

    $this->latestArticlesFilter = function(BlogPost $post) {
        return $post->published > 0
            && !$post->isLink()
            && !$post->hasVideo();
    };
    

    The public service methods passes these variables as a parameter to the filter() method:

        public function getLatestArticles() {
            return $this->filter($this->getPosts(), $this->latestArticlesFilter);
        }
    

    The filter method applies the filter using the PHP array_filter() function :

        private function filter($posts, $filter) {
            return array_filter($posts, $filter);
        }
    

    Here's a simplified version of the service class, combining the parts:

    // The service class to access blog posts.
    class BlogPostService {
    
        // The DAO for blog posts.
        private $dao;
    
        // Filter that recognizes the latest articles.
        private $latestArticlesFilter;
    
        // Filter that recognizes the latest text link posts.
        private $latestLinksFilter;
    
        // Filter that recognizes the latest image link posts.
        private $latestImagesFilter;
    
        // Filter that recognizes the latest video link posts.
        private $latestVideosFilter;
    
        // Creates the blog post service.
        public function __construct($dao) {
            $this->dao = $dao;
    
            // Create filters in constructor, it's not allowed in the variable definition.
            $this->latestArticlesFilter = function(BlogPost $post) {
                return $post->published > 0
                    && !$post->isLink()
                    && !$post->hasVideo();
            };
    
            $this->latestLinksFilter = function(BlogPost $post) {
                return $post->published > 0
                    && $post->isLink()
                    && !$post->hasImages()
                    && !$post->hasVideo();
            };
    
            $this->latestImagesFilter = function(BlogPost $post) {
                return $post->published > 0
                    && $post->isLink()
                    && $post->hasImages();
            };
    
            $this->latestVideosFilter = function(BlogPost $post) {
                return $post->published > 0 && $post->hasVideo();
            };
        }
    
        // Returns the latest published articles.
        public function getLatestArticles() {
            return $this->filter($this->getPosts(), $this->latestArticlesFilter);
        }
    
        // Returns the latest published text link posts.
        public function getLatestLinks() {
            return $this->filter($this->getPosts(), $this->latestLinksFilter);
        }
    
        // Returns the latest published image link posts.
        public function getLatestImages() {
            return $this->filter($this->getPosts(), $this->latestImagesFilter);
        }
    
        // Returns the latest published video link posts.
        public function getLatestVideos() {
            return $this->filter($this->getPosts(), $this->latestVideosFilter);
        }
    
        // Filters posts.
        private function filter($posts, $filter) {
            return array_filter($posts, $filter);
        }
    
        // Returns the latest blog posts.
        private function getPosts() {
            return $this->dao->getStoredPosts();
        }
    
    }
    

    The advantage of this technique is that the selection criteria are defined and contained in variables that can be passed around and used where necessary. I find it a clean solution that is easy to read.

    I understand there are other ways to filter data. The most obvious one is to put the selection in SQL queries on the database and directly select the specific posts.

    But at the moment this blog software uses a storage mechanism that stores PHP objects in the database. There are no specific tables describing the posts, it's just serialized objects. This is easy to use since it doesn't require database changes when the classes change, but performance may not be optimal for all applications. But for now it's good enough for this application.