Skip to content

Instantly share code, notes, and snippets.

@mattkenefick
Last active July 30, 2021 01:16
Show Gist options
  • Save mattkenefick/408c91654487cd9d5dcdd2e730677794 to your computer and use it in GitHub Desktop.
Save mattkenefick/408c91654487cd9d5dcdd2e730677794 to your computer and use it in GitHub Desktop.
Snippets in PHP: PluckMultiple for Laravel
<?PHP
// Setup code
// ...
$emails = Models\User::pluck('email');
<?PHP
// Builder class
// ...
public function pluckMultiple(
// Accept an array of fields, e.g. ['id', 'name']
array $fields,
// Define the glue for implosion, could be empty ''
string $glue = '-'
// Return Laravel collection for chaining more methods
): \Illuminate\Support\Collection
{
// Run basic SELECT `fieldA`, `fieldB`
// ❗️ Might want to modify this to accept all fields
// so you can leverage cached queries.
// ❗️ It's also possible to write the raw query we
// talked about before here
return $this->select($fields)
// Receive all results (❗️ This could get expensive)
->get()
// Run operations on each row, pass in $fields + $glue
// Our code above combines these steps into a single line
->map(function($model, $key) use ($fields, $glue) {
// Get our model as basic array
$arrayOfData = $model->toArray();
// Flip our fields values into their keys position
// e.g. ['id', 'slug'] becomes
// ['id' => 0, 'slug' => 1]
$reversedFields = array_flip($fields);
// Find intersection of keys e.g. 'id' and 'slug'
$intersection = array_intersect_key($arrayOfData, $reversedFields);
// Get only values from resulting intersection
// e.g. [1, 'my-slug']
$values = array_values($intersection);
// Combine values using glue
// e.g. '1-my-slug'
$gluedResult = implode($glue, $values);
// Use this result as our collection item
return $gluedResult;
});
}
<?PHP
namespace App\Builder;
use Illuminate\Database\Eloquent\Builder;
class MyBuilder extends Builder
{
/**
* Selects multiple columns and concatenates them using a specified glue
*
* @param array $fields
* @param string $glue
* @return BaseBuilder
*/
public function pluckMultiple(array $fields, string $glue = '-'): \Illuminate\Support\Collection
{
return $this->select($fields)
->get()
->map(function($model, $key) use ($fields, $glue) {
return implode($glue, array_values(array_intersect_key($model->toArray(), array_flip($fields))));
});
}
}
<?PHP
// Setup code
// ...
$fields = ['id', 'slug'];
$sql = sprintf("
SELECT CONCAT(`%s`) as `concatenatedResult`
FROM `table`
LIMIT 9999
", implode('`, `', $fields));
// Prints:
// SELECT CONCAT(`id`, `slug`) as `concatenatedResult`
// FROM `table`
// LIMIT 9999
<?PHP
use App\Models\MyModel;
$result = MyModel::pluckMultiple(['type', 'slug'], '-')->toArray();
// produces the above output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment