PHPackages                             willv/project - 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. [Framework](/categories/framework)
4. /
5. willv/project

ActiveLibrary[Framework](/categories/framework)

willv/project
=============

A minimal framework for PHP projects

1.1.6(7y ago)242PHP

Since Nov 10Pushed 7y ago2 watchersCompare

[ Source](https://github.com/wvoelcker/project)[ Packagist](https://packagist.org/packages/willv/project)[ RSS](/packages/willv-project/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (8)Dependencies (5)Versions (9)Used By (0)

project
=======

[](#project)

PHP microframework

This is a small framework designed for REST APIs and simple websites. It is very lightweight, and has a shallow stack-trace, meaning that applications run fast and application errors are easy to track down.

how to add to a project via composer
------------------------------------

[](#how-to-add-to-a-project-via-composer)

to add this microframework to your project, you should add it to the 'require' section of composer.json, as follows:

```
"require": {
	"willv/project": "^1.0.0"
}

```

how to use
----------

[](#how-to-use)

### example app

[](#example-app)

The [example app](https://github.com/wvoelcker/project-example-app) can be used to get up and running quickly; just copy it and adapt it to your needs

### directory structure

[](#directory-structure)

The web root should be 'www' and all PHP requests should be routed to www/index.php (other content in the www directory should be static resources only; this microframework does not concern itself with handling them). All 'project' files and directories should be at the same level as the 'www' directory (i.e. one above the web root)

### bootstrapper

[](#bootstrapper)

The microframework contains a bootstrapper object called App that can be used to easily set-up your projects. You should instantiate it in a file called, e.g. "global.php" which you then require in every script that needs to use the framework; typically, the main front-controller for HTTP requests, and any shell scripts that need the environment as well.

### namespace

[](#namespace)

You will need to invent a namespace for your app, for the autoloader to work; see the [example app](https://github.com/wvoelcker/project-example-app) for more details.

### constructors

[](#constructors)

The 'new' keyword is disabled for all classes in this framework; instead, there is a factory method called 'create' which should be called statically (e.g. User::create()). This is because the static-method syntax allows, more versions of PHP, for calling methods on objects in the same line as instantiating them.

### abstract classes

[](#abstract-classes)

Many of the classes in 'project' are abstract classes, meaning that you can't instantiate them directly. Instead you should extend the class with a version relevant for your app, and use that instead. For example, if you are writing a blog app you might have Domain Objects (see below) called User, Post, and Comment. These classes should all extend the base DomainObject class.

### setUp methods

[](#setup-methods)

Many of the abstract classes in 'project' have setUp methods, which is where you should do your configuring (e.g. defining fields in a dataset). See the [example app](https://github.com/wvoelcker/project-example-app) for more details.

### core concepts

[](#core-concepts)

#### domain objects

[](#domain-objects)

Domain objects represent entities used by your app (for example, blog posts, or users). Each domain object is associated with a type of Dataset, meaning that that data submitted for its various properties has a set of validation rules; if you break them, an exception will be thrown.

For example, if you have a domain object called User, you might associate it with a dataset called UserDataset, which contained the fields "name" and "age"

```
$alice = User::create(array("name" => "Alice", "age" => "54"))
$alice->set("age", "55")

```

On both the above lines, the whole dataset will be validated.

#### datasets

[](#datasets)

Datasets are used in two ways:

```
* To validate data submitted by a user
* To validate data associated with a domain object

```

To make a new type of dataset, extend the class \\WillV\\Project\\Dataset; you can then

```
* Instantiate this dataset and call its isValid method to check if a set of data is valid
* Associate the class with a domain object, and it will be used to validate data submitted when creating or changing the domain object

```

To associate a dataset with a domain object, configure it in the relevant domain object's setUp method, like this:

```
class Task extends DomainObject {
	protected function setUp() {
		$this->dataSetName = "\ProjectExampleApp\Datasets\TaskDataset";
	}
}

```

#### data mappers

[](#data-mappers)

Datamappers are used to save domain objects.

At present, there is only one type of datamapper; MySQLMapper, which saves objects to MySQL databases; although more may be added (next on the list is a MongoMapper, which should be a drop-in replacement that saves them to MongoDB instead).

The DataMappers assume that the database schema has fields for "id", "created\_utc" (date created), and "updated\_utc" (date updated) so you should make sure that your database schema contains those fields, or there will be an error.

#### controllers

[](#controllers)

Controllers are simple PHP scripts, which should be placed in a directory called 'controllers'. While being simple scripts, they are included from a context in which they have access to various pieces of information, for example URL parameters, which are available from the array '$this-&gt;urlParams'. They should directly 'echo' their output, and are then free to 'exit'.

#### routing

[](#routing)

Routing should be done by extending the Router class. In the Router's setUp method, you can define routes for most common HTTP methods; parameters should be included in {braces}, and will be available in controllers in the numerically-indexed array $this-&gt;urlParams. When you add a route, there are three parameters; the pattern, the controller-name, and the response type; the latter defaults to text/html. See the [example app](https://github.com/wvoelcker/project-example-app) for more information.

#### 404 and 500 errors

[](#404-and-500-errors)

If you create controllers called 404.php and 500.php these will be used automatically to handle the cases, respectively, of no-such-route and uncaught exceptions.

#### environments

[](#environments)

Environment objects in 'project' store key-value pairs, and a function for determining whether or not the environment is active.

Your app should extend the \\WillV\\Project\\Environment class, configuring your environment with a list of required fields that each environment must provide. You can then instantiate your environments and add them to your environment list (see below).

When instantiating environments, you should provide a list of key/value pairs, and a function to determine if the new environment is active or not. Some of the key/value pairs can be stored in JSON config files, which have the advantage that you can list them in .gitignore so that they will not end up in version control; these are good for storing, for example, access credentials for databases and third-party APIs.

##### environment lists

[](#environment-lists)

You should use an EnvironmentList to store a list of available environments. The getActiveEnvironment method will find the activeEnvironment by calling the appropriate method of each environment in turn, until the active environment is found.

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity11

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity68

Established project with proven stability

 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

Every ~70 days

Recently: every ~81 days

Total

8

Last Release

2615d ago

Major Versions

0.9.0 → 1.0.02018-03-10

### Community

Maintainers

![](https://www.gravatar.com/avatar/47190d6b35a677d3ada56ba57de941800e8031352d63ab646223c41d9327a260?d=identicon)[wvoelcker](/maintainers/wvoelcker)

---

Top Contributors

[![wvoelcker](https://avatars.githubusercontent.com/u/4477562?v=4)](https://github.com/wvoelcker "wvoelcker (365 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/willv-project/health.svg)

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

###  Alternatives

[yiisoft/yii2-swiftmailer

The SwiftMailer integration for the Yii framework

11520.0M473](/packages/yiisoft-yii2-swiftmailer)[rock-symphony/rock-symphony

Fork of symfony 1.4 with dic, form enhancements, latest swiftmailer and better performance

19164.1k3](/packages/rock-symphony-rock-symphony)[wpstarter/framework

The WpStarter Framework - Laravel Framework for WordPress

1810.1k4](/packages/wpstarter-framework)[windwalker/phoenix

A powerful RAD framework to support Rapid Application Development.

1015.7k3](/packages/windwalker-phoenix)[erdiko/core

Erdiko micro MVC core libraries

182.5k4](/packages/erdiko-core)

PHPackages © 2026

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