Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP 3 - Easiest way to retrieve a single field from the database

In CakePHP 2 I could do something like this:

$name = $this->User->field('name', ['email' => '[email protected]']);

In CakePHP 3 you have to do something like this to achieve the same thing:

$users = TableRegistry::get('Users');

$query = $users->find()
    ->select('name')
    ->where(['email' => '[email protected]']);

$name = $query->isEmpty() ? null : $query->first()->name;

Is there a simpler way to perform these kinds of operations? I'm not very familiar with the new ORM.


Edit: I have added an example of a class which adds this behavior for Cake 3:

https://stackoverflow.com/a/42136955/851885

like image 777
BadHorsie Avatar asked Apr 18 '16 18:04

BadHorsie


2 Answers

It's possible to add this functionality to any Table via a custom behavior.

Save as src/Model/Behavior/EnhancedFinderBehavior.php


<?php
namespace App\Model\Behavior;

use Cake\ORM\Behavior;

/**
 * EnhancedFinder behavior
 * 
 * Behavior providing additional methods for retrieving data.
 */
class EnhancedFinderBehavior extends Behavior
{

    /**
     * Retrieve a single field value
     * 
     * @param  string $fieldName The name of the table field to retrieve.
     * @param  array $conditions An array of conditions for the find.
     * @return mixed The value of the specified field from the first row of the result set.
     */
    public function field($fieldName, array $conditions)
    {
        $field = $this->_table->getAlias() . '.' . $fieldName;
        $query = $this->_table->find()->select($field)->where($conditions);

        if ($query->isEmpty()) {
            return null;
        }
        return $query->first()->{$fieldName};
    }
}

Note: for CakePHP versions prior to 3.4, change the code to $this->_table->alias(), which was deprecated in favour of getAlias() in later versions.


Usage

Add the behavior to your class:

<?php
namespace App\Model\Table;

use Cake\ORM\Table;

class UsersTable extends Table
{

    public function initialize(array $config)
    {
        $this->addBehavior('EnhancedFinder');
    }
}

Now you can use the finder like Cake 2:

$name = $this->User->field('name', ['id' => 1]);
like image 177
BadHorsie Avatar answered Nov 26 '22 12:11

BadHorsie


This might be simpler than yours

$users = TableRegistry::get('Users');
$name = $users->get(1)->name;

Make sure that when you use the get function, the parameter should be a primary key in the table.

like image 43
Eric Lee Avatar answered Nov 26 '22 12:11

Eric Lee