tylerssn's avatar

Model not acknowledging new PDO settings

It turns out that in PHP 7.0 and up we have to manually configure PDO to not return the binary version of GUID. To implement the new PDO feature, I added setAttribue to my connection as shown:

    $connection = DB::connection('remoteRecipes');
    $php7GUIDHelper = defined('\PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER');
    if ($php7GUIDHelper):
        $connection->getPdo()->setAttribute(\PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true);
    endif;
    
    return $connection->table('Recipe')...

This resolved my GUID issue. However, the same does not work for models. I tried the following:

    $attributeModel = AttributeOptionsMap::where('apiId', $attribute);
    $php7GUIDHelper = defined('\PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER');
    if ($php7GUIDHelper):
        $attributeModel->getConnection()->getPdo()->setAttribute(\PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true);
    endif;
    $attributeModel = $attributeModel->first();

Should I attempt to manipulate the PDO parameter during the construction of the class? If so, how?

0 likes
2 replies
tylerssn's avatar
tylerssn
OP
Best Answer
Level 3

This actually worked fine. The issue was that my model had a one to many relationship with another table that used GUIDs that I had to apply this same logic to.

Solution - Auto update any models connecting to MSSQL by overriding model boot method

First, I created a scope to update the PDO connection:

<?php 

namespace App\Api\V2\Model\Rule;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class StringifyGuidRule implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder $builder
     * @param  \Illuminate\Database\Eloquent\Model $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        $hasPhp7GuidHelper = defined('\PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER');
        if ($hasPhp7GuidHelper):
            $model->getConnection()->getPdo()->setAttribute(\PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER, true);
        endif;
    }
}

Lastly, add the following to your model class:

/**
 * The "booting" method of the model.
 *
 * @return void
 */
protected static function boot()
{
    parent::boot();

    //Any time this model is used, it will implement the StringifyGuidRule
    static::addGlobalScope(new StringifyGuidRule());
}
1 like
pllaguno's avatar

I know this might be pointless since its a super old post but i am doing that with no success, im using php 7.2 and the scope in actually working since i did dd($hasPhp7GuidHelper); and got true as a return.

what is your $model->getConnection()->getPdo() result? my driver does not change after setAttribute.

PDO {#3015
  inTransaction: false
  attributes: {
    CASE: NATURAL
    ERRMODE: EXCEPTION
    PERSISTENT: false
    DRIVER_NAME: "dblib"
    ORACLE_NULLS: NATURAL
    STATEMENT_CLASS: array:1 [
      0 => "PDOStatement"
    ]
    EMULATE_PREPARES: true
    DEFAULT_FETCH_MODE: BOTH
  }
}

Please or to participate in this conversation.