Задать вопрос

Маленькая реализация ActiveRecord php?

Изучаю паттерны проектирования вот хотелось бы реализовать ActiveRecord тем самым неможко попрактиковаться.
Как реализовать это
$user = new Users();
$user->name = 'Someone';
$user->save();

class AcitveRecord
{
   protected $table;
   public function save(){....}
}
class Users extends ActiveRecord
{
  $this->table = 'Users';
}

Как узнать поля любой таблицы ? Как сущности преобразовать в свойства класса.
  • Вопрос задан
  • 4049 просмотров
Подписаться 4 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 6
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
рекомендую перед изучением паттернов:

1) почитать хотя бы документацию по php что бы ознакомиться с его возможностями
2) почитать хотя бы мельком про SOLID и GRASP
3) и вот теперь изучать паттерны.

php.net/manual/en/language.oop5.magic.php
Ответ написан
Комментировать
Fett
@Fett
Разработчик
Как узнать поля любой таблицы ?

Либо прописываете их в каждой модели:
protected $fields = array('field1', 'field2', ...);

либо при создании объекта, делаете запрос в базу и формируете список полей:
SHOW COLUMNS FROM table_name

Как сущности преоброзовать свойства класса

Используйте магические методы __get и __set

И почитайте, как другие пытаются разрабатывать ActiveRecord
Ответ написан
LittleFatNinja
@LittleFatNinja
горе девелопер, любитель лютой садомии
глянь мой, может что то полезное найдешь
https://github.com/ArtemRochev/ORM/blob/master/Dat...

я его еще не допилил
Ответ написан
Комментировать
dmitriylanets
@dmitriylanets
веб-разработчик
можно посмотреть как это делается тут:
phpactiverecord.org
propelorm.org
Ответ написан
@atambalasi Автор вопроса
У меня пока что получилось вот так
сам класс AR
namespace Core\Db;

use Core\Db\DBConnect;

class Model
{
	public $table;
	protected $fields = [];
	protected $properties = [];
	private $_conn = null;
	
	public function __construct()
	{
		$dbConfig = require 'core/database.php';
		$getInstance = DBConnect::getInstance($dbConfig);
		$this->_conn = $getInstance->getConnection();
		
		$className = strtolower(get_class($this));
		$temp_tbname = str_replace('models\\', '', $className);
		$this->table = strtolower($temp_tbname);
		$this->getColumnName();
	}
	public function __set($name, $value)
	{
		$this->properties[$name] = $value;
	}
	public function __get($name) 
    {
        if (array_key_exists($name, $this->fields)) {
            return $this->properties[$name];
        }
    }
	private function getColumnName()
	{
		 foreach($this->_conn->query("SHOW COLUMNS FROM users") as $column)
		 {
		 	if($column['Extra'] != 'auto_increment')
		 		$this->fields[] = $column['Field'];
		 }
		 return $this->fields;
	}

	public function save()
	{
		$bindParamNames = [];
		
		foreach($this->fields as $field)
		{
			 $bindParamNames[] = ":". $field;	
		}
		var_dump($bindParamNames);
		
		$fields = implode(', ', $this->fields);
		$bindParamNamesString = implode(', ', $bindParamNames);
		$stmt = $this->_conn->prepare("INSERT INTO " . $this->table . " (" . $fields. ") VALUES (" . $bindParamNamesString .  ")");
		foreach($bindParamNames as $param)
		{
			$key = str_replace(':', '', $param);
			$stmt->bindParam($param, $this->properties[$key]);
		}
		$stmt->execute();
		
	}

}

Класс User наследует Model
namespace Models;

use Core\Db\Model;

class Users extends Model
{
	
}

Пример
use Models\Users;

$user = new Users();

$user->email = 'google@gmail.com';
$user->name = "User88";
$user->save();

Класс сохранять в бд данные, но я совсем не увернь что реализовал паттерн ActiveRecord. Или все такие какой-то степени реализация AR есть ?
Ответ написан
trevoga_su
@trevoga_su
очень рекомендую почитать фаулера мартина и отказаться от AR
DataMapper во многом лучше - вы разделяете доменные объекты и слой, который их гоняет в базу и обратно
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы