PHPackages                             yuanqing/fi - 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. [File &amp; Storage](/categories/file-storage)
4. /
5. yuanqing/fi

AbandonedArchivedLibrary[File &amp; Storage](/categories/file-storage)

yuanqing/fi
===========

Query a collection of text files like a document database in PHP.

v0.2.0(11y ago)115MITPHP

Since Jul 24Pushed 11y ago1 watchersCompare

[ Source](https://github.com/yuanqing/fi)[ Packagist](https://packagist.org/packages/yuanqing/fi)[ Docs](https://github.com/yuanqing/fi)[ RSS](/packages/yuanqing-fi/feed)WikiDiscussions master Synced 1mo ago

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

Fi.php [![Packagist Version](https://camo.githubusercontent.com/50c4ce355daffc3253e93d942ae7cbf580547717f73c7b32f9c766756a47e027/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7975616e71696e672f66692e737667)](https://packagist.org/packages/yuanqing/fi) [![Build Status](https://camo.githubusercontent.com/9dbdb452a1e406ae580041c092d11660027921d882db2035869435dd41c6d391/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f7975616e71696e672f66692e737667)](https://travis-ci.org/yuanqing/fi) [![Coverage Status](https://camo.githubusercontent.com/f162451ec4f4bbaff9071bdcfa12a67dccd26aa572f560cbe8de82d793cf4e21/68747470733a2f2f696d672e736869656c64732e696f2f636f766572616c6c732f7975616e71696e672f66692e737667)](https://coveralls.io/r/yuanqing/fi)
=====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================

[](#fiphp---)

Fi lets you query a collection of text files, as if the folder of files were a database (well, almost).

Fi (rhymes with *pie*) is designed to be used as part of a [static site generator](http://staticsitegenerators.net/).

Super quick start
-----------------

[](#super-quick-start)

There is [a documented, runnable example](https://github.com/yuanqing/fi/blob/master/example) you can play with:

```
$ git clone https://github.com/yuanqing/fi
$ cd fi
$ composer install
$ php example/example.php

```

There are also [tests](https://github.com/yuanqing/fi/blob/master/test/FiTest.php).

Quick start
-----------

[](#quick-start)

Suppose we have organised our text files into neat date-based folders like so:

```
data/
|-- _defaults.md
`-- 2014/
    |-- 01/
    |   |-- _defaults.md
    |   |-- 01-foo.md
    |   |-- 02-bar.md
    |   `-- ...
    |-- 02/
    |   `-- ...
    `-- ...

```

Each text file contains [YAML frontmatter](http://jekyllrb.com/docs/frontmatter/) and content. The file `01-foo.md` might be something like:

```
---
title: foo title
---
foo content

```

We would query our `data` directory like so:

```
$dataDir = 'data';
$filePathFormat = '{{ date.year: 4d }}/{{ date.month: 2d }}/{{ date.day: 2d }}-{{ title: s }}.md';
$collection = Fi::query($dataDir, $filePathFormat); #=> Collection object
```

Every file that matches the given `$filePathFormat` is a **Document**. A **Collection**, then, is simply an [Iterator](http://php.net/manual/en/class.iterator.php) over a set of Documents:

```
foreach ($collection as $document) {
  $document->getFilePath(); #=> 'data/2014/01/01-foo.md', ...
  $document->getField('title'); #=> 'foo title', ...
  $document->getField('date'); #=> ['year' => 2014, 'month' => 1, 'day' => 1], ...
  $document->getContent(); #=> 'foo content', ...
}
```

We can also access a Document directly by index:

```
$document = $collection->getDocument(0); #=> Document object
$document->getFilePath(); #=> 'data/2014/01/01-foo.md'
$document->getField('title'); #=> 'foo title'
$document->getField('date'); #=> ['year' => 2014, 'month' => 1, 'day' => 1]
$document->getContent(); #=> 'foo content'
```

### Map, filter, sort

[](#map-filter-sort)

Fi also supports **map**, **filter**, and **sort** operations over our Collection of Documents:

```
# set the date to a DateTime object
$collection->map(function($document) {
  $date = DateTime::createFromFormat('Y-m-d', implode('-', $document->getField('date')));
  return $document->setField('date', $date);
});

# filter out Documents with date 2014-01-01
$collection->filter(function($document) {
  return $document->getField('date') != DateTime::createFromFormat('Y-m-d', '2014-01-01');
});

# sort by date in descending order
$collection->sort(function($document1, $document2) {
  return $document1->getField('date') < $document2->getField('date');
});
```

### Default values

[](#default-values)

A text file will inherit default values (for fields or content) from any `_defaults.md` file found in the same directory, or in a parent directory. Defaults are said to **cascade**; `_defaults.md` files found further down the file hierarchy will *overwrite* those higher up the hierarchy.

API
---

[](#api)

### Fi

[](#fi)

#### Fi::query ( string $dataDir, string $filePathFormat \[, string $defaultsFileName = '\_defaults.md' \] )

[](#fiquery--string-datadir-string-filepathformat--string-defaultsfilename--_defaultsmd--)

Makes a Collection object.

```
$dataDir = './data';
$filePathFormat = '{{ year: 4d }}/{{ month: 2d }}/{{ date: 2d }}-{{ title: s }}.md';
$collection = Fi::query($dataDir, $filePathFormat);
```

- `$dataDir` is the directory where Fi will look for text files that match the `$filePathFormat`.
- `$filePathFormat` is specified using a Regex-like syntax; see [Extract.php](https://github.com/yuanqing/extract).
- `$defaultsFileName` is the name of the text file that Fi will look for when resolving defaults.
-

### Collection

[](#collection)

#### map ( callable $callback )

[](#map--callable-callback-)

Applies the `$callback` to each Document in the Collection. Returns the Collection object.

```
# sets the title of all Documents to 'foo'
$collection->map(function($document) {
  $document->setField('title', 'foo');
  return $document;
}); #=> Collection
```

- `$callback` takes a single argument of type Document. It must return an object of type Document.

#### filter ( callable $callback )

[](#filter--callable-callback-)

Filter out Documents in the Collection using the `$callback`. Returns the Collection object.

```
# filters out Documents with the title 'foo'
$collection->filter(function($document) {
  return $document->getField('title') !== 'foo';
}); #=> Collection
```

- `$callback` takes a single argument of type Document. Return false to *exclude* that Document from the Collection.

#### sort ( callable $callback )

[](#sort--callable-callback-)

Sorts the Collection using the `$callback`. Returns the Collection object.

```
# sorts by title in ascending order
$collection->sort(function($document1, $document2) {
  return strnatcasecmp($document1->getField('title'), $document2->getField('title'));
}); #=> Collection
```

- `$callback` takes two arguments of type Document. Return `1` if the first Document argument is to be ordered before the second, else return `-1`.

#### sort ( mixed $fieldName \[, int $sortOrder = Fi::ASC \] )

[](#sort--mixed-fieldname--int-sortorder--fiasc--)

Sorts the Collection by the `$fieldName` in the specified `$sortOrder`. Returns the Collection object.

```
# sorts by title in ascending order
$collection->sort('title', Fi::ASC); #=> Collection

# sorts by title in descending order
$collection->sort('title', Fi::DESC); #=> Collection
```

- `$sortOrder` must be either `Fi::ASC` or `Fi::DESC`.

#### toArr ( )

[](#toarr--)

Gets all the Documents in the Collection as an array.

```
$collection->toArr(); #=> [Document, Document, ...]
```

-

### Document

[](#document)

#### getFilePath ( )

[](#getfilepath--)

Gets the file path of the text file (relative to the `$dataDir`) that corresponds to the Document.

```
$document->getFilePath(); #=> 'data/2014/01/01-foo.md'
```

#### getFields ( )

[](#getfields--)

Gets all the fields of the Document.

```
$document->getFields(); #=> ['title' => 'foo', 'date' => ['year' => 2014, 'month' => 1, 'day' => 1]]
```

#### hasField ( mixed $fieldName )

[](#hasfield--mixed-fieldname-)

Checks if the Document has a field with the specified `$fieldName`.

```
$document->hasField('title'); #=> true
```

#### getField ( mixed $fieldName )

[](#getfield--mixed-fieldname-)

Gets the value of the specified `$fieldName`.

```
$document->getField('title'); #=> 'foo'
```

#### setField ( mixed $fieldName, mixed $fieldValue )

[](#setfield--mixed-fieldname-mixed-fieldvalue-)

Sets the field with `$fieldName` to the specified `$fieldValue`. Returns the Document object.

```
$document->setField('title', 'bar'); #=> Document
```

#### hasContent ( )

[](#hascontent--)

Checks if the Document content is non-empty.

```
$document->hasContent(); #=> true
```

#### getContent ( )

[](#getcontent--)

Gets the Document content.

```
$document->getContent(); #=> 'bar'
```

#### setContent ( string $content )

[](#setcontent--string-content-)

Sets the Document content to the specified `$content`. Returns the Document object.

```
$document->setContent('baz'); #=> Document
```

-

Requirements
------------

[](#requirements)

Fi requires at least **PHP 5.3** or **HHVM**, and [Composer](http://getcomposer.org/).

Installation
------------

[](#installation)

1. Install [Composer](http://getcomposer.org/).
2. Install [the Composer package](https://packagist.org/packages/yuanqing/fi):

    ```
    $ composer require yuanqing/fi ~0.2

    ```
3. In your PHP file, require the Composer autoloader:

    ```
    require_once __DIR__ . '/vendor/autoload.php';
    ```

Testing
-------

[](#testing)

You need [PHPUnit](http://phpunit.de/) to run the tests:

```
$ git clone https://github.com/yuanqing/fi
$ cd fi
$ composer install
$ phpunit

```

License
-------

[](#license)

[MIT license](https://github.com/yuanqing/fi/blob/master/LICENSE)

###  Health Score

24

—

LowBetter than 32% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

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

Every ~2 days

Total

2

Last Release

4312d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5aebd62c372779a1223fca7819cdd898e82698e011b7617aaf822042710a55ec?d=identicon)[yuanqing](/maintainers/yuanqing)

---

Tags

filestaticodmfrontmatterdocument

### Embed Badge

![Health badge](/badges/yuanqing-fi/health.svg)

```
[![Health](https://phpackages.com/badges/yuanqing-fi/health.svg)](https://phpackages.com/packages/yuanqing-fi)
```

###  Alternatives

[league/flysystem

File storage abstraction for PHP

13.6k639.1M2.2k](/packages/league-flysystem)[league/flysystem-aws-s3-v3

AWS S3 filesystem adapter for Flysystem.

1.6k263.6M790](/packages/league-flysystem-aws-s3-v3)[knplabs/gaufrette

PHP library that provides a filesystem abstraction layer

2.5k39.8M123](/packages/knplabs-gaufrette)[league/flysystem-local

Local filesystem adapter for Flysystem.

226231.8M39](/packages/league-flysystem-local)[fof/upload

The file upload extension for the Flarum forum with insane intelligence.

188171.7k15](/packages/fof-upload)[league/flysystem-memory

In-memory filesystem adapter for Flysystem.

8533.6M194](/packages/league-flysystem-memory)

PHPackages © 2026

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