How to convert an array into an object by Reflection + Attribute


In daily development, we may encounter situations where we interact with third-party APIs. General APIs return data in json format, we convert json to array, and all that remains is to manipulate arrays to complete our business logic. However, manipulating arrays can sometimes be a headache. In the programming world, manipulating object s is more understandable than manipulating arrays, and IDE Tips are also more friendly.

Actual Scene

We need to parse the user's resume information, but OCR is not our main business, so we bought a third-party OCR parsing. The resume returns complex data, and we have to deal with some fields specially. For example, gender,The returned data is string type, but our database is int type, not only the data type is different, but also the field name may be different, so we need to do data conversion at this time. But the returned data is too complex, not only gender, but also school information in academic qualifications and so on.


To solve these problems, a powerful Hydrate can be implemented by reflecting Reflection+Annotation Attribute. Let's look at code usage before analyzing how it is implemented.



composer require kabunx/hydrate -vvv

Define Entity

namespace App\Entities;

use Carbon\Carbon;
use Kabunx\Hydrate\Entity;
use Kabunx\Hydrate\Source;

 * Resume Subject Information
class Resume extends Entity
    protected string $sourceKeyFormat = 'studly';

    public int $type = 0;

    public string $resumeGrade = '';

    // The field has changed here
    public bool $isMarried = false;

    // Omit other fields here (more than 30)

    // English Level Certificate, Highest College Certificate Preferred
    public ?EnglishGrade $englishGrade;
     * Computer (IT) Skills
     * @var array|It[]
    public array $its = []

    public function setIsMarried(?string $value): bool
        return $value ? ($value == 'yes' ? true : false) : false;

    // IT Skills
    public function setIts(?array $its): array
        if (is_null($its)) {
            return [];
        $entities = [];
        foreach ($its as $it) {
            $entities[] = It::instance($it);
        return $entities;

 * English Achievement
class EnglishGrade extends Entity
  protected string $sourceKeyFormat = 'studly';
  public string $nameOfCertificate = '';

  public string $score = '';

  public ?Carbon $receivingDate;

 * IT Skills
class It extends Entity
  protected string $sourceKeyFormat = 'studly';
  // Skill categories
  public string $skillType = '';

  // Usage Time
  #[Source("TimeOfUse", "used_at")]
  public string $usedTime = '';

  // Mastery Level
  public string $competencyLevel = '';


use App\Entities\Resume;
// Here simulates the API's return data
$data = [
    "Type" => 1,
    "ResumeGrade" => '',
    "Married" => 'yes',
    "GradeOfEnglish" => [
        "NameOfCertificate" => "",
        "Score" => "excellent",
        "ReceivingDate" => "2021-01-01"
    "ITSkills" => [
            "skillType" => "",
            "TimeOfUse" => "",
            "CompetencyLevel" => ""

// How to convert to entity
$entity = Resume::instance($data);
// entity is now operational

// How to convert to the data we want
// Will be converted according to your comment, default is snake format

Whether it's convenient or not, I often use it in my actual work. I replaced the original doctrine/annotations with the original annotations.
In entity, we can use setProperty to modify data, which is the same idea as the model modifier in laravel.

Source Parsing

Specific code has been put on GitHub by me, address hydrate
You can look at it first, and I'll add notes later.

Tags: Laravel

Posted on Mon, 20 Sep 2021 09:45:26 -0400 by champoi