Doktrin Timestampable Unix zaman damgası kullanın

2 Cevap php

Nasıl Doktrini Timestampable davranışları ile Unix damgalarını kullanabilirim? Ben aşağıdaki kod parçacığını here buldum, ama yerine elle her yerde bu eklemek istemiyorum:

$this->actAs('Timestampable', array(
'created' => array('name' => 'created_at',
    'type'    =>  'integer',
    'format'  =>  'U',
    'disabled' => false,
    'options' =>  array()),
'updated' => array('name'    =>  'updated_at',
    'type'    =>  'integer',
    'format'  =>  'U',
    'disabled' => false,
    'options' =>  array())));

2 Cevap

Bu aslında, ben ilk düşündüğüm daha kolay bir cevap alabilirsiniz bir soru ...

Diyelim ki şimdi ne ile başlayalım:

  • a model class, that extends Doctrine_Record
    • Benim örnek (ler) için, Test bu sınıf arayacak.
    • Bu Test modelinde, Timestampable Davranışı, ancak UNIX zaman damgası ile değil, datetime değerleri kullanmak istiyorum
    • And you want this without having to write lots of configuration stuff in your models.
      (I can understand that : less risk to forget one line somewhere and at wrong data in DB)
  • A project that is configured and everything
    • Hangi Eğer Doktrini ile şeyler biliyor demektir
    • ve ben temelleri hakkında konuşmak olmaz ki

A solution to this problem would be to not use the default Timestampable behaviour that comes with Doctrine, but another one, that you will define.
Which means, in your model, you will have something like this at the bottom of setTableDefinition method :

$this->actAs('MyTimestampable');

(I suppose this could go in the setUp yöntem, çok btw - belki de) aslında gerçek bir yer olurdu


What we now have to do is define that MyTimestampable behaviour, so it does what we want.
As Doctrine's Doctrine_Template_Timestampable already does the job quite well (except for the format, of course), we will inherit from it ; hopefully, it'll mean less code to write ;-)

Yani, biz bu gibi bizim davranış sınıfını beyan:

class MyTimestampable extends Doctrine_Template_Timestampable
{
    // Here it will come ^^
}

Şimdi, Doctrine_Template_Timestampable aslında Doktrini kodu kaynağında, ne bir göz atalım:

  • yapılandırması biraz (the two created_at ve updated_at alanları)
  • Ve bir dinleyici kaydeden aşağıdaki satırı:


$this->addListener(new Doctrine_Template_Listener_Timestampable($this->_options));

Kullanıcının bu bir kaynağını bir göz atalım; Biz bu bölümü dikkat edin:

if ($options['type'] == 'date') {
    return date($options['format'], time());
} else if ($options['type'] == 'timestamp') {
    return date($options['format'], time());
} else {
    return time();
}

Bu durum, iki created_at ve updated_at alanların özellikleri date ne timestamp değilse, Doctrine_Template_Listener_Timestampable anlamına gelir otomatik olarak bir UNIX zaman damgası kullanın - ne kadar rahat!


As you don't want to define the type to use for those fields in every one of your models, we will modify our MyTimestampable class.
Remember, we said it was extending Doctrine_Template_Timestampable, which was responsible of the configuration of the behaviour...

Bu yüzden, date ve timestamp 'den a type kullanılmamasından, bu yapılandırma geçersiz kılar:

class MyTimestampable extends Doctrine_Template_Timestampable
{
    protected $_options = array(
        'created' =>  array('name'          =>  'created_at',
                            'alias'         =>  null,
                            'type'          =>  'integer',
                            'disabled'      =>  false,
                            'expression'    =>  false,
                            'options'       =>  array('notnull' => true)),
        'updated' =>  array('name'          =>  'updated_at',
                            'alias'         =>  null,
                            'type'          =>  'integer',
                            'disabled'      =>  false,
                            'expression'    =>  false,
                            'onInsert'      =>  true,
                            'options'       =>  array('notnull' => true)));
}

Biz modeli MyTimestampable olarak hareket değil, Timestampable ... Yani, şimdi, sonucu görelim olduğunu daha önce yaptığı açıklamada, ;-)

Biz bu modeli sınıfı düşünün Test:

class Test extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->setTableName('test');
        $this->hasColumn('id', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'unsigned' => 0,
             'primary' => true,
             'autoincrement' => true,
             ));
        $this->hasColumn('name', 'string', 32, array(
             'type' => 'string',
             'length' => 32,
             'fixed' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('value', 'string', 128, array(
             'type' => 'string',
             'length' => 128,
             'fixed' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('created_at', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'unsigned' => 0,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('updated_at', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'unsigned' => 0,
             'primary' => false,
             'notnull' => false,
             'autoincrement' => false,
             ));
        $this->actAs('MyTimestampable');
    }
}

Hangi aşağıdaki MySQL tabloya eşler:

CREATE TABLE  `test1`.`test` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(32) NOT NULL,
  `value` varchar(128) NOT NULL,
  `created_at` int(11) NOT NULL,
  `updated_at` int(11) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

Biz tablo bu şekilde iki satır oluşturabilirsiniz:

$test = new Test();
$test->name = 'Test 1';
$test->value = 'My Value 2';
$test->save();

$test = new Test();
$test->name = 'Test 2';
$test->value = 'My Value 2';
$test->save();

Biz DB değerleri kontrol ederseniz, biz böyle bir şey alırsınız:

mysql> select * from test;
+----+--------+----------------+------------+------------+
| id | name   | value          | created_at | updated_at |
+----+--------+----------------+------------+------------+
|  1 | Test 1 | My Value 1     | 1248805507 | 1248805507 |
|  2 | Test 2 | My Value 2     | 1248805583 | 1248805583 |
+----+--------+----------------+------------+------------+
2 rows in set (0.00 sec)

Yani, biz satır oluşturulması için Tamam, öyle görünüyor ;-)


Ve şimdi, ikinci satır getirme ve güncelleme atalım:

$test = Doctrine::getTable('Test')->find(2);
$test->value = 'My New Value 2';
$test->save();

Ve, geri DB, biz şimdi bu olsun:

mysql> select * from test;
+----+--------+----------------+------------+------------+
| id | name   | value          | created_at | updated_at |
+----+--------+----------------+------------+------------+
|  1 | Test 1 | My Value 1     | 1248805507 | 1248805507 |
|  2 | Test 2 | My New Value 2 | 1248805583 | 1248805821 |
+----+--------+----------------+------------+------------+
2 rows in set (0.00 sec)

updated_at alan güncellendi, ve created_at alanı değişmedi; Tamam görünüyor ki çok ;-)


Yani, kurşun puan bir çift şey, kısa fit yapmak ve biraz özetlemek için:

  • Bizim model sınıf kendi MyTimestampable gibi davranır, değil varsayılan Timestampable
  • Bizim davranış Doktrini bir tane uzanır
  • And only override it's configuration
    • İstediğimiz kadar bizim modellerin her birinde yalnızca bir kod satırı ile, kullanabilirsiniz.


I will let you do some more intensive tests, but I hope this helps !
Have fun :-)

Bir yöntem kaydedilmeden önce kayıt getirilen ve ne zaman bir unix zaman damgası eşdeğer oluşturmak için doctorine en dinleyicileri kullanmak olacaktır:

class Base extends Doctrine_Record_Listener
{
    public function preHydrate(Doctrine_Event $event)
    {
        $data = $event->data;

        $data['unix_created_at'] = strtotime($data['created_at']);
        $data['unix_updated_at'] = strtotime($data['updated_at']);

        $event->data = $data;
    }
}

Bu created_at ve updated_at işlevlerini ihtiyacı şey uzatmak baz sınıf olabilir.

Ben $ veri aracılığıyla döngü olabilir biraz daha fazla müdahalesi ile eminim ve tüm datetime alanları 'unix_'. $ Field_name dönüştürebilirsiniz.

İyi şanslar