Soru ve beklentiler
Bu sorunun gerçek formu bağlamda pratik olsa da (yıl 1899) teorik anlamda biraz belirsizdir. Kaç yaşında Geçmişe ne kadar gitmek isteyebiliriz ? Gelecek hakkında ne düşünüyorsun?
WordPress, bloglama motoru olarak başladığından beri, bu bağlamsal olarak, aşağıdaki zaman aralığını ele almak için gelişti:
- WP'nin var olduğu tarihler (açıkça kullanabilmek için)
- olası tarihsel yayınların aralığı (dolaylı olarak internet var olduğu kadar)
- özel çaba sarf etmeden mümkün olduğunca geleceğe kadar (kırılana kadar çalışın)
WordPress kullanımı, blog oluşturmayan uygulamalara dönüştükçe, bu tür projeler (genellikle raporlardan gördüğüm tarih ve sanat), bu aralığın dışındaki tarihlerle çeşitli sorunları vurmaya başladı.
Araştırmamın amacı için aşağıdaki soruları formüle etmiştim:
- WordPress posta tarihleriyle doğal ve güvenilir bir şekilde kullanılabilecek en eski ve en yeni iki takvim yılı nedir?
- Mevcut aralığın doğal aralığın ötesine genişletilmesi için düşük asılı meyveler (varsa) nelerdir?
Platform sınırlamaları
WordPress PHP uygulaması olduğundan ve veri depolama için MySQL kullandığından sınırlamalarına tabidir.
MySQL
WordPress yazı tarihlerini MySQL'de tür post_date
sütununda saklar DATETIME
.
Belgelere göre bu tip 1000 ila 9999 yıllarını destekler :
DATETIME
Tip tarih ve saat parçaları her ikisini de içerir değerler için kullanılır. MySQL DATETIME
değerleri alır ve 'YYYY-MM-DD HH:MM:SS'
formatta görüntüler . Desteklenen aralığı '1000-01-01 00:00:00'
için '9999-12-31 23:59:59'
.
Bununla birlikte, önceki değerlerin işe yarayabileceğini söylüyor, daha sonraki değerlerden bahsedilmiyor:
İçin DATE and DATETIME
aralık açıklamaları, önceki değerler çalışabilir, ancak hiçbir garantisi olmadığı anlamına gelir “desteklenen”.
Ampirik olarak aralık dışı çalışma değerlerini gözlemledim, ancak bu anekdot ve güvenilirlik durumumuzdan düşüyor.
PHP
PHP programlamasında Unix zaman damgası tarih gösterimi yaygın olarak kullanılmaktadır. Amaçlarımız için olan belgelere göre (PHP 5.2+ ve genel 32 bit ortam) 1902 ila 2037 yıllarını (tam olarak) destekler :
Zaman damgasının geçerli aralığı genellikle Fri, 13 Dec 1901 20:45:54 UTC
ila arasındadır Tue, 19 Jan 2038 03:14:07 UTC
. (Bunlar, 32 bit işaretli tam sayı için minimum ve maksimum değerlere karşılık gelen tarihlerdir.) Ayrıca, tüm platformlar negatif zaman damgalarını desteklemez, bu nedenle tarih aralığınız Unix döneminden daha erken olamaz. Bu, örneğin önceki tarihlerin Jan 1, 1970
Windows, bazı Linux dağıtımları ve diğer birkaç işletim sisteminde çalışmayacağı anlamına gelir . PHP 5.1.0 ve daha yeni sürümleri bu sınırlamanın üstesinden gelir.
Bunun dışında yeni Date/Time
tabanlı işlem 64 bit ve kabaca -292 milyar ila 292 milyar yıl arasındadır , bu da muhtemelen insanlık ihtiyaçlarını şu anda aşmaktadır.
WordPress sınırlamaları
WordPress, kod tabanına bazı ek sınırlamalar getirir ve devralır.
Veri akışı
Temel kullanıcı iş akışı bakış açısından, tarihle ilgili olarak işlenmiş iki tane vardır:
- düzenleme sonrası formdaki tarih girişi doğru şekilde işlenmeli ve veritabanına kaydedilmelidir
- veritabanına kaydedilen tarih doğru okunmalı ve arayüzde gösterilmelidir
Bunların teknik olarak tamamen farklı ve bağımsız süreçler olduğunu unutmayın. Daha fazla açıklandığı gibi, aralıkları üst üste gelmez ve doğru tarihin kaydedilmesi, WordPress ortamında doğru okuma yeteneği ile eşit değildir.
Açık limitler
- Yönetici içinde WordPress yazı editörü, 100 ila 9999 arası yayın tarihi olarak gönderilebilen yıl aralığına izin verir
_wp_translate_postdata()
süreç yılı (formdan ayrı sayı olarak gönderilir) ve:
- negatif olmayan > 0 olarak dezenfekte eder
- 1 ile 32767 arasında sınır uygulayan
wp_checkdate()
PHP yerli adını kullanan doğrularcheckdate()
Örtük sınırlar
strtotime()
PHP işlevi birden çok kez kullanılır ve yukarıda belirtilen Unix zaman damgasına tabidir, en düşük düzeyde mysql2date()
veritabanından tüm tarih okumalarını etkiler, 1902'den 2037'ye devralınan aralık
- WordPress, tarih ayrıştırma için düzenli ifadeye geri döner
get_gmt_from_date()
, bu da yılı bekler ([0-9]{1,4})
, 1 ile 9999 arasında sınırlar, daha kapsamlı kod denetiminin numaralandırılmasını gerektiren diğer işlevlerde benzer işleme olasılığı
Geçici çözüm olasılığı
wp_checkdate()
wp_checkdate
bu doğrulama kontrolünü geçersiz kılmaya izin veren bir filtreye sahip
- yoluyla, son kullanıcı yönelik çıkış gider
date_i18n()
sahip olan date_i18n
hareket aralığı (zaten üzerinden geçirilir filtre, teorik olarak tamamen tarihleri kesişme ve yeniden işlem çıkış zorlu ancak arayüz sağlar false
) zaman damgası girişi
Sonuçlar
Verilerin pratik amaçları ve taşınabilirliği için WordPress yazı tarihi aralığı 32 bit Unix zaman damgasınınkine eşit gibi gözükmektedir ve 1902-2037 yıllarını kapsamaktadır .
Bu aralık dışındaki herhangi bir son tarih işlemi için ortam denetlenmelidir (64 bit Unix zaman damgaları, fiili çalışan MySQL veya alternatif veritabanı depolama değerleri). Daha uzak aralıklar için ( 1000'in altında, 9999'un üzerinde ) önemli miktarda özel kod gerekli olabilir.
Keyfi tarihlerin herhangi bir uygulaması için:
- bunları MySQL'de veritabanı sınırlamalarına tabi olmayan bir biçimde saklar
- tamamen özel
Date/Time
tabanlı kod ve / veya Unix zaman damgası sınırlarından etkilenmeyecek şekilde denetlenmiş WordPress işlevleri kullanılarak PHP'de işlem
Kod test yatağı
Aşağıdaki kod ve elle seçilmiş yıllar kümesi, yukarıdaki araştırmalar ve sonuçların test edilmesi için kullanılmıştır:
require ABSPATH . '/wp-admin/includes/post.php';
$timestamp_size_info = array(
'PHP_INT_SIZE' => PHP_INT_SIZE,
'PHP_INT_MAX' => number_format( PHP_INT_MAX ),
'min timestamp' => date( DATE_ISO8601, - PHP_INT_MAX ),
'zero timestamp' => date( DATE_ISO8601, 0 ),
'max timestamp' => date( DATE_ISO8601, PHP_INT_MAX ),
);
r( $timestamp_size_info );
// hand picked set of years to test for assorted limits
$years = array(
'negative' => - 1,
'zero' => 0,
'one' => 1,
'wp min' => 100,
'mysql first' => 1000,
'before unix' => 1899,
'unix first' => 1902,
'current' => 2013,
'unix last' => 2037,
'after unix' => 2039,
'mysql last, wp max' => 9999,
'after checkdate' => 33000,
);
// simulates form submission data
$post = array(
'post_type' => 'post', // shut notice
'edit_date' => 1,
'aa' => 1,
'mm' => '01',
'jj' => '01',
'hh' => '00',
'mn' => '00',
'ss' => '00',
);
// add_filter( 'wp_checkdate', '__return_true' );
foreach ( $years as $name => $year ) {
$post['aa'] = $year;
$translated = _wp_translate_postdata( false, $post );
if ( is_wp_error( $translated ) ) { // wp_checkdate() failed
r( array( 'year' => $year . " ({$name})", 'translated valid' => false ) );
}
else {
$post_date = $translated['post_date'];
$post_date_gmt = $translated['post_date_gmt'];
$translated_valid = (string) $year == substr( $post_date, 0, strpos( $post_date, '-' ) );
$mysql2date = mysql2date( DATE_ISO8601, $post_date );
$mysql2date_valid = (string) $year == substr( $mysql2date, 0, strpos( $mysql2date, '-' ) );
r( array(
'year' => $year . " ({$name})",
'post_date' => $post_date,
'translated valid' => $translated_valid,
'post_date_gmt' => $post_date_gmt,
'mysql2date' => $mysql2date,
'from sql valid' => $mysql2date_valid,
) );
}
}