PHPackages                             vlucas/spot - 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. [Database &amp; ORM](/categories/database)
4. /
5. vlucas/spot

ActiveLibrary[Database &amp; ORM](/categories/database)

vlucas/spot
===========

DataMapper ORM for PHP 5.3+

v2.x-dev(11y ago)7672414[9 issues](https://github.com/vlucas/Spot/issues)[2 PRs](https://github.com/vlucas/Spot/pulls)1BSDPHPPHP &gt;=5.3.2

Since Nov 1Pushed 11y ago11 watchersCompare

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

READMEChangelogDependencies (2)Versions (12)Used By (1)

Spot PHP ORM
============

[](#spot-php-orm)

For RDBMS (Currently has a MySQL and Sqlite adapter)

DEPRECATION NOTICE
------------------

[](#deprecation-notice)

**WORK ON THIS PROJECT HAS STOPPED**. Please use [Spot v2](https://github.com/vlucas/spot2) instead - it is actively maintained, and is based on a more solid foundation in the Doctrine DBAL (database abstraction layer, not Doctrine ORM), and had much wider and mroe robust database support (MySQL, SQLite, PostgreSQL, SQLServer, Oracle, etc.).

Using Spot In Your Project
--------------------------

[](#using-spot-in-your-project)

Spot is a standalone ORM that can be used in any project. Follow the instructions below to get Spot setup in your project, or use a pre-coded plugin for the framework you are using:

[Silex provider](https://github.com/psamatt/SpotServiceProvider) by [@psamatt](https://github.com/psamatt)

Connecting to a Database
------------------------

[](#connecting-to-a-database)

The `Spot\Config` object stores and references database connections by name. Create a new instance of `Spot\Config` and add database connections with DSN strings so Spot can establish a database connection.

```
$cfg = new \Spot\Config();
// MySQL
$adapter = $cfg->addConnection('test_mysql', 'mysql://user:password@localhost/database_name');
// Sqlite
$adapter = $cfg->addConnection('test_sqlite', 'sqlite://path/to/database.sqlite');
```

If you are using Sqlite, the Sqlite filename must be the name of your database followed by the extension e.g `blogs.sqlite`

Accessing the Mapper
--------------------

[](#accessing-the-mapper)

Since Spot follows the DataMapper design pattern, you will need a mapper instance for working with object Entities and database tables.

```
$mapper = new \Spot\Mapper($cfg);
```

Since you have to have access to your mapper anywhere you use the database, most people create a helper method to create a mapper instance once and then return the same instance when required again. Such a helper method might look something like this:

```
function get_mapper() {
    static $mapper;
    if($mapper === null) {
        $mapper = new \Spot\Mapper($cfg);
    }
    return $mapper;
}
```

Creating Entities
-----------------

[](#creating-entities)

Entity classes can be named and namespaced however you want to set them up within your project structure. For the following examples, the Entities will just be prefixed with an `Entity` namespace for easy psr-0 compliant autoloading.

```
namespace Entity;

class Post extends \Spot\Entity
{
    protected static $_datasource = 'posts';

    public static function fields()
    {
        return array(
            'id' => array('type' => 'int', 'primary' => true, 'serial' => true),
            'title' => array('type' => 'string', 'required' => true),
            'body' => array('type' => 'text', 'required' => true),
            'status' => array('type' => 'int', 'default' => 0, 'index' => true),
            'date_created' => array('type' => 'datetime')
        );
    }

    public static function relations()
    {
        return array(
            // Each post entity 'hasMany' comment entites
            'comments' => array(
                'type' => 'HasMany',
                'entity' => 'Entity_Post_Comment',
                'where' => array('post_id' => ':entity.id'),
                'order' => array('date_created' => 'ASC')
            )
        );
    }
}
```

### Built-in Field Types

[](#built-in-field-types)

All the basic field types are built-in with all the default functionality provided for you:

- `string`
- `int`
- `float/double/decimal`
- `boolean`
- `text`
- `date`
- `datetime`
- `timestamp`
- `year`
- `month`
- `day`

#### Registering Custom Field Types

[](#registering-custom-field-types)

If you want to register your own custom field type with custom functionality on get/set, have a look at the clases in the `Spot\Type`namespace, make your own, and register it in `Spot\Config`:

```
$config->typeHandler('string', '\Spot\Type\String');
```

Migrations / Creating and Updating Tables
-----------------------------------------

[](#migrations--creating-and-updating-tables)

Spot comes with a method for running migrations on Entities that will automatically CREATE and ALTER tables based on the current Entity's `fields` definition.

```
$mapper->migrate('Post');
```

Your database should now have the `posts` table in it, with all the fields you described in your `Post` entity.

Finders (Mapper)
----------------

[](#finders-mapper)

The main finders used most are `all` to return a collection of entities, and `first` or `get` to return a single entity matching the conditions.

### all(entityName, \[conditions\])

[](#allentityname-conditions)

Find all `entityName` that matches the given conditions and return a `Spot\Entity\Collection` of loaded `Spot\Entity` objects.

```
// Conditions can be the second argument
$posts = $mapper->all('Entity\Post', array('status' => 1));

// Or chained using the returned `Spot\Query` object - results identical to above
$posts = $mapper->all('Entity\Post')->where(array('status' => 1));
```

Since a `Spot\Query` object is returned, conditions and other statements can be chained in any way or order you want. The query will be lazy-executed on interation or `count`, or manually by ending the chain with a call to `execute()`.

### first(entityName, \[conditions\])

[](#firstentityname-conditions)

Find and return a single `Spot\Entity` object that matches the criteria.

```
$post = $mapper->first('Entity\Post', array('title' => "Test Post"));
```

Or `first` can be used on a previous query with `all` to fetch only the first matching record.

```
$post = $mapper->all('Entity\Post', array('title' => "Test Post"))->first();
```

### Conditional Queries

[](#conditional-queries)

```
# All posts with a 'published' status, descending by date_created
$posts = $mapper->all('Entity\Post')
    ->where(array('status' => 'published'))
    ->order(array('date_created' => 'DESC'));

# All posts created before today
$posts = $mapper->all('Entity\Post')
    ->where(array('date_created
