Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Orm Laravel Package

cycle/orm

Cycle ORM is a fast, flexible PHP DataMapper ORM for long-running apps. Works with plain PHP objects, dynamic schemas, and powerful query builder. Supports relations, eager/lazy loading, migrations, and MySQL/Postgres/SQLite/SQL Server.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require cycle/orm

For annotations support (optional):

composer require cycle/annotated
  1. Define an Entity:

    use Cycle\Annotated\Annotation\Entity;
    use Cycle\Annotated\Annotation\Column;
    
    #[Entity]
    class User
    {
        #[Column(type: 'primary')]
        public int $id;
    
        #[Column(type: 'string')]
        public string $name;
    }
    
  2. Configure ORM: Create a config file (e.g., config/cycle.php):

    return [
        'orm' => [
            'connection' => 'default',
            'entities' => [
                __DIR__.'/../app/Entities',
            ],
        ],
    ];
    
  3. Bootstrap ORM:

    use Cycle\ORM\ORM;
    use Cycle\Database\DatabaseManager;
    
    $db = DatabaseManager::create(['default' => 'pgsql://user:pass@localhost/db']);
    $orm = ORM::create($db, include __DIR__.'/config/cycle.php');
    
  4. First Query:

    $user = $orm->getRepository(User::class)->find(1);
    

First Use Case: CRUD Operations

// Create
$user = new User();
$user->name = 'John Doe';
$orm->getRepository(User::class)->persist($user)->run();

// Read
$user = $orm->getRepository(User::class)->find(1);

// Update
$user->name = 'Updated Name';
$orm->getRepository(User::class)->persist($user)->run();

// Delete
$orm->getRepository(User::class)->delete($user)->run();

Implementation Patterns

Repository Pattern

Cycle ORM leverages repositories for database operations. Each entity has a dedicated repository:

$userRepo = $orm->getRepository(User::class);

// Fetch all
$users = $userRepo->findAll();

// Fetch with conditions
$activeUsers = $userRepo->select()->where('active', true)->fetchAll();

Query Builder

Cycle provides a fluent query builder:

$users = $userRepo
    ->select(['name', 'email'])
    ->where('age', '>', 18)
    ->orderBy('name', 'ASC')
    ->limit(10)
    ->fetchAll();

Relationships

Define relationships in your entity:

#[Entity]
class Post
{
    #[Column(type: 'primary')]
    public int $id;

    #[Column(type: 'string')]
    public string $title;

    #[BelongsTo(target: User::class)]
    public User $author;
}

Load relationships:

// Eager loading
$posts = $postRepo
    ->load('author')
    ->fetchAll();

// Lazy loading
$post = $postRepo->find(1);
$author = $post->author; // Loaded on-demand

Transactions

Use Unit of Work (UoW) for transactions:

$uow = $orm->getUow();
$uow->persist($user);
$uow->persist($post);
$uow->run(); // Commits transaction

Embedded Entities

Define embedded entities for complex data:

#[Embeddable]
class Address
{
    #[Column(type: 'string')]
    public string $street;
}

#[Entity]
class Customer
{
    #[Embedded]
    public Address $address;
}

Query Scopes

Create reusable query scopes:

#[Entity]
class Product
{
    #[Column(type: 'string')]
    public string $name;

    #[Column(type: 'integer')]
    public int $price;

    #[Scope]
    public function active(): Select
    {
        return $this->select()->where('active', true);
    }
}

// Usage
$activeProducts = $productRepo->active()->fetchAll();

Active Record Pattern (Optional)

Use cycle/active-record for AR-style entities:

use Cycle\ActiveRecord\ActiveRecord;

class User extends ActiveRecord
{
    public int $id;
    public string $name;
}

// Usage
$user = User::find(1);
$user->name = 'Updated';
$user->save();

Gotchas and Tips

Common Pitfalls

  1. Transaction Management:

    • Always use run() to execute transactions. Forgetting this will leave operations pending.
    • Example:
      $uow = $orm->getUow();
      $uow->persist($entity);
      // $uow->run(); // Don't forget this!
      
  2. Lazy Loading:

    • Lazy-loaded relationships trigger additional queries. Use eager loading (load()) for performance-critical paths.
    • Example:
      // Avoid N+1 queries
      $posts = $postRepo->load('author')->fetchAll();
      
  3. Entity State:

    • Cycle ORM tracks entity state (new, modified, deleted). Ensure you persist entities explicitly.
    • Example:
      $user = new User();
      $user->name = 'John';
      $userRepo->persist($user); // Required to mark as new
      
  4. Cyclic References:

    • Be cautious with bidirectional relationships to avoid infinite loops.
    • Example:
      #[ManyToMany(target: Tag::class)]
      public Collection $tags;
      
      #[ManyToMany(target: Post::class, inverse: 'tags')]
      public Collection $posts;
      

Debugging Tips

  1. Enable Query Logging:

    $db = DatabaseManager::create([
        'default' => [
            'dsn' => 'pgsql://user:pass@localhost/db',
            'logging' => true, // Enable query logging
        ],
    ]);
    
  2. Use toSql(): Convert queries to SQL for debugging:

    $query = $userRepo->select()->where('active', true);
    echo $query->toSql(); // Outputs raw SQL
    
  3. Check Entity State: Use getState() to inspect entity state:

    $state = $userRepo->getState($user);
    

Configuration Quirks

  1. Connection Management:

    • Ensure your database connection is properly configured in DatabaseManager.
    • Example:
      $db = DatabaseManager::create([
          'default' => [
              'dsn' => 'pgsql://user:pass@localhost/db',
              'options' => [
                  'charset' => 'utf8mb4',
              ],
          ],
      ]);
      
  2. Entity Mapping:

    • Cycle ORM supports multiple mapping strategies (annotations, attributes, YAML). Choose one and stick with it.
    • Example for PHP 8 Attributes:
      use Cycle\Annotated\Annotation\Entity;
      
      #[Entity]
      class User { ... }
      
  3. Schema Introspection:

    • Use cycle/schema-provider to introspect existing databases:
      $provider = new DoctrineProvider($db);
      $schema = $provider->getSchema();
      

Extension Points

  1. Custom Mappers:

    • Extend Cycle\ORM\Mapper\MapperInterface to handle custom mapping logic.
    • Example:
      class CustomMapper implements MapperInterface
      {
          public function map(array $data, EntityInterface $entity): void
          {
              // Custom mapping logic
          }
      }
      
  2. Query Scopes:

    • Create global query scopes by implementing Cycle\ORM\Select\ScopeInterface.
    • Example:
      class ActiveScope implements ScopeInterface
      {
          public function apply(Select $select): Select
          {
              return $select->where('active', true);
          }
      }
      
  3. Event Subscribers:

    • Use Cycle\ORM\Event\EventManager to listen to ORM events (e.g., prePersist, postLoad).
    • Example:
      $eventManager = $orm->getEventManager();
      $eventManager->addListener('prePersist', function ($event) {
          $entity = $event->getEntity();
          $entity->createdAt = new DateTime();
      });
      
  4. Custom Collections:

    • Implement Cycle\ORM\Collection\CollectionInterface for custom collection behavior.
    • Example:
      class CustomCollection implements CollectionInterface
      {
          public function getIterator(): Iterator
          {
              // Custom iterator logic
          }
      }
      

Performance Tips

  1. Batch Operations: Use bulk operations for performance:

    $userRepo->deleteMany()->where('active', false)->run();
    
  2. Selective Loading: Load only necessary fields:

    $users = $userRepo->select(['id', 'name'])->fetchAll();
    
  3. Caching: Use cycle/database caching features for frequent queries:

    $db = DatabaseManager::create([
        'default' => [
            'dsn' =>
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
yandex/translate-api
voku/simple_html_dom
league/flysystem-vfs
bkwld/upchuck
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php