PHP code example of utopia-php / database

1. Go to this page and download the library: Download utopia-php/database library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

utopia-php / database example snippets


use Utopia\Database\Database;
use Utopia\Database\Filter\Callback;

$database = new Database($adapter, $cache, [
    new Callback('trim', fn (mixed $value) => \trim($value), fn (mixed $value) => $value),
]);

use Utopia\Database\Document;

// Define a custom document class
class User extends Document
{
    public function getEmail(): string
    {
        return $this->getAttribute('email', '');
    }

    public function isAdmin(): bool
    {
        return $this->getAttribute('role') === 'admin';
    }
}

// Register the custom type
$database->setDocumentType('users', User::class);

// Now all documents from 'users' collection are User instances
$user = $database->getDocument('users', 'user123');
$email = $user->getEmail(); // Use custom methods
if ($user->isAdmin()) {
    // Domain logic
}



use Utopia\Cache\Adapter\Memory;
use Utopia\Cache\Cache;
use Utopia\Database\Adapter\MariaDB;
use Utopia\Database\Database;
use Utopia\Database\PDO;

$host = 'mariadb';
$port = 3306;

$pdo = new PDO("mysql:host={$host};port={$port};charset=utf8mb4", 'root', 'password', [
    \PDO::ATTR_TIMEOUT => 3,
    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_EMULATE_PREPARES => true,
    \PDO::ATTR_STRINGIFY_FETCHES => true,
]);

$cache = new Cache(new Memory()); // or use any cache adapter you wish

$database = new Database(new MariaDB($pdo), $cache);



use Utopia\Cache\Adapter\Memory;
use Utopia\Cache\Cache;
use Utopia\Database\Adapter\MySQL;
use Utopia\Database\Database;
use Utopia\Database\PDO;

$host = 'mysql';
$port = 3306;

$pdo = new PDO("mysql:host={$host};port={$port};charset=utf8mb4", 'root', 'password', [
    \PDO::ATTR_TIMEOUT => 3,
    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_EMULATE_PREPARES => true,
    \PDO::ATTR_STRINGIFY_FETCHES => true,
]);

$cache = new Cache(new Memory()); // or use any cache adapter you wish

$database = new Database(new MySQL($pdo), $cache);



use Utopia\Cache\Adapter\Memory;
use Utopia\Cache\Cache;
use Utopia\Database\Adapter\Postgres;
use Utopia\Database\Database;
use Utopia\Database\PDO;

$host = 'postgres';
$port = 5432;

$pdo = new PDO("pgsql:host={$host};port={$port}", 'root', 'password', [
    \PDO::ATTR_TIMEOUT => 3,
    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_EMULATE_PREPARES => true,
    \PDO::ATTR_STRINGIFY_FETCHES => true,
]);

$cache = new Cache(new Memory()); // or use any cache adapter you wish

$database = new Database(new Postgres($pdo), $cache);



use Utopia\Cache\Adapter\Memory;
use Utopia\Cache\Cache;
use Utopia\Database\Adapter\SQLite;
use Utopia\Database\Database;
use Utopia\Database\PDO;

$path = '/path/to/database.sqlite';

$pdo = new PDO("sqlite:{$path}", null, null, [
    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_STRINGIFY_FETCHES => true,
]);

$cache = new Cache(new Memory()); // or use any cache adapter you wish

$database = new Database(new SQLite($pdo), $cache);



use Utopia\Cache\Adapter\Memory;
use Utopia\Cache\Cache;
use Utopia\Database\Adapter\Mongo;
use Utopia\Database\Database;
use Utopia\Mongo\Client; // from utopia-php/mongo

$client = new Client('database', 'mongo', 27017, 'root', 'password', true);

$cache = new Cache(new Memory()); // or use any cache adapter you wish

$database = new Database(new Mongo($client), $cache);

use Utopia\Database\Hook\Permissions;
use Utopia\Database\Hook\Relationships;

// Writes, moves and deletes the permission rows that MariaDB, MySQL and SQLite check document permissions
// against. PostgreSQL checks the row's own _permissions column; MongoDB, Memory and Redis keep permissions
// with the document.
$database->addHook(new Permissions());

// Populates related documents and handles nested writes and cascades
$database->addHook(new Relationships());

use Utopia\Database\Event;
use Utopia\Database\Event\Document\Created;
use Utopia\Database\Event\Document\Deleted;
use Utopia\Database\Event\Domain;
use Utopia\Database\Hook\Lifecycle;
use Utopia\Database\Hook\Named;
use Utopia\Database\Hook\Selective;

final class AuditLog implements Lifecycle, Named, Selective
{
    /** @var list<string> */
    public array $entries = [];

    public function getName(): string
    {
        return 'audit-log';
    }

    public function handles(Event $event): bool
    {
        return $event === Event::DocumentCreate || $event === Event::DocumentDelete;
    }

    public function handle(Domain $event): void
    {
        if ($event instanceof Created || $event instanceof Deleted) {
            $this->entries[] = $event->event->value.':'.$event->document->getId();
        }
    }
}

$auditLog = new AuditLog();
$database->addHook($auditLog);

// Run a callback without the named hooks, or without any hook when no names are given
$database->silent(fn () => $database->ping(), ['audit-log']);

use Utopia\Database\Collection;
use Utopia\Database\Event;
use Utopia\Database\Hook\Queries;
use Utopia\Database\Query;

final class PublicNames implements Queries
{
    public function rewrite(Event $event, Collection $collection, array $queries): array
    {
        return \array_map(
            static fn (Query $query): Query => $query->getMethod()->isJoin() && $query->getAttribute() === 'public-movies'
                ? (clone $query)->setAttribute('movies')
                : $query,
            $queries,
        );
    }
}

$database->addHook(new PublicNames());

use Utopia\Database\Capability;

// Get namespace
$database->getNamespace();

// Sets namespace that prefixes all collection names
$database->setNamespace(
    namespace: 'namespace'
);

// Get default database
$database->getDatabase();

// Sets default database
$database->setDatabase(
    name: 'dbName'
);

// Check if a database exists
if ($database->exists(database: 'dbName')) {
    // Delete a database
    $database->delete(
        database: 'dbName'
    );
}

// Creates a new database.
// Uses default database as the name.
$database->create();

// Renames a database
$database->update(
    database: 'dbName',
    new: 'archive'
);

// Returns an array of all databases
$database->list();

// Check if collection exists
$database->collectionExists(
    collection: 'users',
    database: 'dbName'
);

// Ping database it returns true if the database is alive
$database->ping();

// Get Database Adapter
$database->getAdapter();

// Limits, capabilities and features of the adapter
$profile = $database->profile();
$profile->limits->keywords; // names that cannot be used as attribute keys
$profile->supports(Capability::Joins);

use Utopia\Database\Attribute;
use Utopia\Database\Collection;
use Utopia\Database\Collection\Update;
use Utopia\Database\Index;
use Utopia\Database\Permission;
use Utopia\Database\Role;
use Utopia\Query\OrderDirection;

// Creates a new collection named 'users'. The SQL adapters store it as the table '$namespace_users',
// with the table '$namespace_users_perms' for its document permissions.
$database->createCollection(Collection::create(
    id: 'users',
    attributes: [
        Attribute::string('name', size: 256),
        Attribute::integer('age'),
    ],
    indexes: [
        Index::key('idx_name', ['name'], lengths: [256], orders: [OrderDirection::Asc]),
        Index::key('idx_name_age', ['name', 'age'], lengths: [128, null], orders: [OrderDirection::Asc, OrderDirection::Desc]),
    ],
    permissions: [
        Permission::create(Role::any()),
        Permission::read(Role::any()),
    ],
    documentSecurity: true,
));

// Update Collection Permissions; a field left null keeps its stored value
$database->updateCollection('users', new Update(
    permissions: [
        Permission::create(Role::any()),
        Permission::read(Role::any()),
        Permission::update(Role::any()),
        Permission::delete(Role::any()),
    ],
    documentSecurity: true,
));

// Get Collection; throws Exception\NotFound when it does not exist
$collection = $database->getCollection('users');
$collection->attributes(); // list of Attribute
$collection->indexes(); // list of Index

// Find Collection; null when it does not exist
$database->findCollection('users');

// List Collections
$database->listCollections(
    limit: 25,
    offset: 0
);

// Delete cached documents of a collection
$database->purgeCachedCollection('users');

// Deletes the collection and its permissions table
$database->createCollection(Collection::create(id: 'drafts'));
$database->deleteCollection('drafts');

use Utopia\Database\Attribute;
use Utopia\Database\Attribute\Update;
use Utopia\Database\Collection;
use Utopia\Database\Format;
use Utopia\Database\IntegerWidth;
use Utopia\Database\Permission;
use Utopia\Database\Role;
use Utopia\Database\Validator\Structure;
use Utopia\Query\Schema\ColumnType;
use Utopia\Validator\Range;

$database->createCollection(Collection::create(
    id: 'movies',
    permissions: [
        Permission::create(Role::any()),
        Permission::read(Role::any()),
        Permission::update(Role::any()),
        Permission::delete(Role::any()),
    ],
));

// Creates a new attribute named 'name' in the 'movies' collection and returns the stored attribute.
// Every type has a factory: Attribute::string(), integer(), float(), boolean(), datetime(), point(), ...
$database->createAttribute('movies', Attribute::string('name', size: 128, >updateAttribute('movies', 'year', new Update(
    

use Utopia\Database\Index;
use Utopia\Query\OrderDirection;

// Every index type has a factory: Index::key(), unique(), fulltext(), trigram(), spatial(), object(), ttl(),
// hnswEuclidean(), hnswCosine() and hnswDot(). Orders are OrderDirection::Asc and OrderDirection::Desc.

// Creates a new index named 'index1' in the 'movies' collection and returns the stored index.
$database->createIndex('movies', Index::key(
    'index1',
    ['name', 'year'],
    lengths: [128, null],
    orders: [OrderDirection::Asc, OrderDirection::Desc]
));

// Creates several indexes and writes the collection definition once
$database->createIndexes('movies', [
    Index::fulltext('index_name_search', ['name']),
    Index::unique('index_director_year', ['director', 'year']),
]);

// Rename index from old to new in the 'movies' collection.
$database->renameIndex(
    collection: 'movies',
    old: 'index1',
    new: 'index2'
);

// Deletes the index in the 'movies' collection.
$database->deleteIndex('movies', 'index2');

use Utopia\Database\Attribute;
use Utopia\Database\Collection;
use Utopia\Database\Permission;
use Utopia\Database\Relationship;
use Utopia\Database\Relationship\Update;
use Utopia\Database\RelationshipDeleteAction;
use Utopia\Database\Role;

// Each relationship type has a factory: Relationship::oneToOne(), oneToMany(), manyToOne() and manyToMany().
// What happens to related documents when a document is deleted is a RelationshipDeleteAction:
// Restrict (the default), Cascade or SetNull.

// Creates a relationship between the two collections with the default reference attributes:
// 'users' on 'movies', and 'movies' on 'users'
$database->createRelationship('movies', Relationship::oneToOne('users', twoWay: true));

// Create a relationship with custom reference attributes
$database->createCollection(Collection::create(
    id: 'reviews',
    attributes: [Attribute::string('body', size: 1024)],
    permissions: [Permission::create(Role::any()), Permission::read(Role::any())],
));

$database->createRelationship('movies', Relationship::oneToMany(
    'reviews',
    key: 'reviews',
    twoWay: true,
    twoWayKey: 'movie',
    onDelete: RelationshipDeleteAction::Cascade
));

// Update the relationship with the default reference attributes
$database->updateRelationship('movies', 'users', new Update(
    onDelete: RelationshipDeleteAction::SetNull
));

// Update the relationship with custom reference attributes
$database->updateRelationship('movies', 'users', new Update(
    key: 'viewer',
    twoWayKey: 'favoriteMovie',
    twoWay: true
));

// Delete the relationship with the default or custom reference attributes
$database->deleteRelationship('movies', 'viewer');

use Utopia\Database\Document;
use Utopia\Database\Id;
use Utopia\Database\Permission;
use Utopia\Database\PermissionType;
use Utopia\Database\Query;
use Utopia\Database\Role;
use Utopia\Database\SetType;

// Id helpers
Id::unique(padding: 12); // Creates an id of 13 characters from uniqid() followed by 12 random hex characters
Id::custom(id: 'my_user_3235');

// Role helpers
Role::any();
Role::guests();
Role::user(
    identifier: Id::unique(),
    status: 'verified' // optional
);
Role::users();
Role::team(
    identifier: Id::unique()
);
Role::team(
    identifier: Id::unique(),
    dimension: '123' // team:id/dimension
);
Role::label(
    identifier: 'admin'
);
Role::member(
    identifier: Id::unique()
);

// Permission helpers
Permission::read(Role::any());
Permission::create(Role::user(Id::unique()));
Permission::update(Role::user(Id::unique(padding: 23)));
Permission::delete(Role::user(Id::custom(id: 'my_user_3235')));

// To create a document
$document = new Document([
    '$permissions' => [
        Permission::read(Role::any()),
        Permission::update(Role::user(Id::custom('1x'))),
        Permission::delete(Role::user(Id::unique(12))),
    ],
    '$id' => Id::unique(),
    'name' => 'Captain Marvel',
    'director' => 'Anna Boden & Ryan Fleck',
    'year' => 2019,
    'price' => 25.99,
    'active' => true,
    'genres' => ['science fiction', 'action', 'comics'],
]);

$document = $database->createDocument(
    collection: 'movies',
    document: $document
);

// Get which collection a document belongs to
$document->getCollection();

// Get document id
$document->getId();

// Check whether document in empty
$document->isEmpty();

// Increase an attribute in a document
$database->increaseDocumentAttribute(
    collection: 'movies',
    id: $document->getId(),
    attribute: 'price',
    value: 5,
    max: 100
);

// Decrease an attribute in a document
$database->decreaseDocumentAttribute(
    collection: 'movies',
    id: $document->getId(),
    attribute: 'price',
    value: 5,
    min: 0
);

// Update the value of an attribute in a document

// Set types are cases of SetType:
// SetType::Assign assigns the new value directly (the default),
// SetType::Append appends the new value to the end of an array,
// SetType::Prepend prepends the new value to the start of an array.
// Appending or prepending to an attribute that is not an array sets it to an array containing the new value.
$document->setAttribute('name', 'Captain Marvel (2019)')
         ->setAttribute('genres', 'superhero', SetType::Append);

$document = $database->updateDocument(
    collection: 'movies',
    id: $document->getId(),
    document: $document
);

// Update the permissions of a document
$document->setAttribute('$permissions', Permission::read(Role::users()), SetType::Append)
         ->setAttribute('$permissions', Permission::update(Role::users()), SetType::Append);

$document = $database->updateDocument(
    collection: 'movies',
    id: $document->getId(),
    document: $document
);

// Roles that have permission to read, update and delete the document
$document->getPermissionsByType(PermissionType::Read);
$document->getPermissionsByType(PermissionType::Update);
$document->getPermissionsByType(PermissionType::Delete);

// The document as an array, with or without some top-level keys
$document->only(['name', 'year']);
$document->except(['$permissions']);

// Get document with all attributes
$database->getDocument(
    collection: 'movies',
    id: $document->getId()
);

// Get document with a sub-set of attributes
$database->getDocument(
    collection: 'movies',
    id: $document->getId(),
    queries: [
        Query::select(['name', 'director', 'year'])
    ]
);

// Find documents

// Query Types
$queries = [
    Query::equal(attribute: 'name', values: ['Captain Marvel', 'Frozen']),
    Query::notEqual(attribute: 'director', value: 'Unknown'),
    Query::lessThan(attribute: 'year', value: 2030),
    Query::lessThanEqual(attribute: 'year', value: 2030),
    Query::greaterThan(attribute: 'year', value: 2000),
    Query::greaterThanEqual(attribute: 'year', value: 2000),
    Query::containsAny(attribute: 'genres', values: ['action', 'comics']), // array attributes
    Query::containsString(attribute: 'director', values: ['Boden']), // string attributes
    Query::between(attribute: 'year', start: 2000, end: 2030),
    Query::search(attribute: 'name', value: 'Marvel'), // needs a fulltext index on the attribute
    Query::select(['name', 'year']),
    Query::orderDesc(attribute: 'year'),
    Query::orderAsc(attribute: 'name'),
    Query::isNull(attribute: 'director'),
    Query::isNotNull(attribute: 'director'),
    Query::startsWith(attribute: 'name', value: 'Captain'),
    Query::endsWith(attribute: 'director', value: 'Fleck'),
    Query::limit(value: 35),
    Query::offset(value: 0),
];

$database->find(
    collection: 'movies',
    queries: [
        Query::equal(attribute: 'name', values: ['Captain Marvel (2019)']),
        Query::notEqual(attribute: 'year', value: 2020)
    ]
);

// Find a document
$database->findOne(
    collection: 'movies',
    queries: [
        Query::equal(attribute: 'name', values: ['Captain Marvel (2019)']),
        Query::lessThan(attribute: 'year', value: 2030)
    ]
);

// Read every match in batches of 100; a limit() caps how many are yielded
foreach ($database->cursor('movies', [Query::greaterThan('year', 2000)], batchSize: 100) as $movie) {
    $movie->getId();
}

// Get count of documents
$database->count(
    collection: 'movies',
    queries: [
        Query::equal(attribute: 'name', values: ['Captain Marvel (2019)']),
        Query::greaterThan(attribute: 'year', value: 2000)
    ],
    max: 1000 // Max is optional
);

// Get the sum of an attribute from all the documents
$database->sum(
    collection: 'movies',
    attribute: 'price',
    queries: [
        Query::greaterThan(attribute: 'year', value: 2000)
    ],
    max: null // max = null means no limit
);

// Delete a cached document
// Note: Cached Documents or Collections are automatically deleted when a document or collection is updated or deleted
$database->purgeCachedDocument('movies', $document->getId());

// Delete documents in batches of at most Database::BATCH_SIZE; onNext receives each deleted document
$deleted = [];
$database->deleteDocuments(
    collection: 'movies',
    queries: [Query::lessThan(attribute: 'year', value: 1900)],
    onNext: function (Document $document) use (&$deleted): void {
        $deleted[] = $document->getId();
    }
);

// Delete a document
$database->deleteDocument(
    collection: 'movies',
    id: $document->getId()
);

use Utopia\Database\Document;
use Utopia\Database\Query;

$movie = $database->createDocument('movies', new Document([
    'name' => 'Frozen',
    'director' => 'Chris Buck & Jennifer Lee',
    'year' => 2013,
    'price' => 19.99,
    'active' => true,
    'genres' => ['animation'],
]));

$database->createDocument('reviews', new Document([
    'body' => 'A classic',
    'movie' => $movie->getId(),
]));

// Join the reviews to their movies, aliased 'm'
$database->find('reviews', [
    Query::join('movies', 'm', [Query::on('movie', '$id')]),
    Query::select(['body', 'm.name']),
]);

// Aggregate: one row per group, holding the groups and the aggregates
$database->aggregate('movies', [
    Query::count('*', 'movies'),
    Query::avg('price', 'averagePrice'),
    Query::groupBy(['active']),
]);
bash
composer