WordPress'te PHP ile Özel Tablo Oluşturma
WordPress'te özel bir tablo oluşturmak için ne gerektiğini veya neden istediğinizi veya ihtiyaç duyduğunuzu hiç merak ettiniz mi? WordPress, kullanıma hazır verileri depolamanın birçok farklı yolu ile birlikte gelir. Neyse ki bizim için WordPress, her ihtiyacımızı onunla birlikte gelen hazır çözümlere uydurmaya zorlanmayacağımız kadar esnektir.
MySQL'e dayalı bir PHP uygulaması olarak, ihtiyaçlarımızı daha kesin karşılamak için veritabanında kendi tablolarımızı oluşturma seçeneğimiz de var. Bazen MVP veya 1.0 için mükemmel bir çözüm olabilecek şey, yazılım geliştikçe doğru seçim olmayabilir.
Bu makalede, önyükleme için bir yükseltme rutininin yanı sıra özel bir tablo oluşturma sürecini de inceleyeceğiz.
Giriş Komutu ile tanışın
WordPress alanında bir geliştirici olarak gerçekten keyif aldığım şeylerden biri de kendi açık kaynak projelerime katkıda bulunmak. Bunların en bilinenlerinden biri (GitHub yıldızlarını sayarsanız), siteniz için “sihirli” giriş bağlantıları oluşturmanıza izin veren WP-CLI paketi olan WP CLI Login Command projemdir. Delicious Brains müşterisiyseniz, gönderdiğimiz bazı e-postalarda bunun gibi bir bağlantı görmüş olabilirsiniz; tıkladığınızda hemen hesabınızda oturum açarsınız – şifre gerekmez. Bu sadece müşterilerimiz için çok kullanışlı olmakla kalmaz, aynı zamanda bu tür bir iş akışı geliştirme aşamasında da büyük bir zaman tasarrufu sağlayabilir.
Geçenlerde, bir sonraki ana sürümde çığır açmaya hazırlanırken paketin bazı yönlerini yeniden düşünmeye başladım, bu da komutun verilerini WordPress'te nerede ve nasıl sakladığını yeniden düşünmeme neden oldu.
İleride, bu projeyi özel bir tablo kullanmaktan fayda sağlayabilecek bir kod tabanı örneği olarak kullanacağız. Paketin içine çok fazla girmeyeceğiz, ancak bağlam için pratik bir örnek olarak kullanacağız.
TABLO OLUŞTURMAK veya <> TABLO OLUŞTURMAK için mi?
Özel bir tablo oluşturmaya başlamadan önce, bunun benzersiz durumunuz için doğru çözüm olup olmadığını düşünmek önemlidir.
Buna yaklaşmanın bir yolu, ideal şemanızı (verilerinizin rüya gibi özel tablolarınızda sahip olacağı yapı) ve WordPress tarafından sağlanan mevcut şemaları karşılaştırmaktır.
Varsayılan WordPress veritabanının manzarasına özellikle aşina değilseniz, Iain'in WordPress Veritabanına Yönelik Ultimate Geliştirici Kılavuzu ile kendinizi hızlandırmak için bir dakikanızı ayırmak isteyebilirsiniz.
Acele etmeyin; seni bekleyeceğiz
Şemanız kavramsal olarak bir Gönderi modeline uyuyor mu? Yani, veri modelinizde bir başlık, birincil içerik, zaman damgalarında oluşturulmuş veya değiştirilmiş veya bilgi var mı veya buna ihtiyaç var mı? Öyleyse, özel bir gönderi türü kullanmaktan daha iyi olabilirsiniz. WordPress'in kendisi, gezinme menüsü öğeleri ve özelleştirici anlık görüntü değişiklik setleri gibi asla düşünemeyeceğiniz şeyler için gönderi türlerini kullanır!
Veri modeliniz bir anahtar/değer şemasına daha mı uygun? Basit anahtar/değer depolaması söz konusu olduğunda WordPress'in birçok seçeneği vardır (punto amaçlanmamıştır). Kullanıcı, gönderi, terim ve yorum meta verileri, geçici olaylar, seçenekler ve nesne önbellek API'leri bu amaca hizmet eder (ve bu, çoklu site sayılmaz).
Gönderiler, meta veriler ve diğer hazır WordPress kalıcılık stratejileriyle ilgili sorun, şemanın sabitlenmiş olmasıdır. Bir seçenek, değeri depolamak için yalnızca bir sütuna sahiptir. Aynı şey her türlü meta, geçici olay ve önbellek için de geçerlidir. Bir dizi gibi ilkel olmayan bir değeri depolamak için, onu serileştirmeye veya değeri birden çok anahtara (yani veritabanındaki birden çok satıra) bölmek zorunda kalırız. Özel bir tablo kullanmanın belki de birincil faydalarından biri, artık verileri seri hale getirmemize gerek olmamasıdır . Serileştirme, depolama için uygundur, ancak onu etkin bir şekilde sorgulama yeteneğimizi büyük ölçüde azaltır. Kendi tablonuzu kullanmak, ihtiyaçlarınız için en iyi şemayı tasarlamanıza olanak tanır. Bu size verilerinizi sorgulama konusunda tam bir özgürlük verir ve son derece güçlü olabilir.
Özel Tablo Oluşturma
Yeni bir tablo oluştururken, şemayı ilk seferde doğru yapmak önemlidir, çünkü bu daha sonra değiştirmek zahmetli olabilir. Şema, tablonun planı gibidir. Her bir sütunu ve buna uygulanabilecek tüm nitelikleri tanımlamamız gerekir. Giriş Komutu için aşağıdaki sütunlara ihtiyacımız olacak:
-
public_key– Sihirli URL'de kullanılan anahtar. -
private_key– Oturum açma kimlik doğrulaması için gizli anahtar. -
user_id– Sihirli oturum açmanın kimliğini doğrulayacağı kullanıcının kimliği. -
created_at– Oturum açmanın oluşturulduğu tarih ve saat. -
expires_at– Oturum açmanın sona erdiği tarih ve saat.
WordPress tarafından kullanılan veritabanında yeni bir tablo oluşturmak, onu oluşturmak için SQL ifadesini yazmak ve ardından bunu dbDelta işlevine geçirmek kadar basittir. Kullanılması bir gereklilik olmasa da, mevcut tablo yapısını incelediği, istenen tablo yapısıyla karşılaştırdığı ve gerektiğinde tabloyu eklediği veya değiştirdiği için veritabanında değişiklik yaparken işlev önerilir.
global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE `{$wpdb->base_prefix}cli_logins` ( public_key varchar(255) NOT NULL, private_key varchar(255) NOT NULL, user_id bigint(20) UNSIGNED NOT NULL, created_at datetime NOT NULL, expires_at datetime NOT NULL, PRIMARY KEY (public_key) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql);
WordPress veritabanında bir tablo adına başvururken genellikle $wpdb->prefix kullanmanız gerektiğini unutmayın. Bu önek, kullanıcı tarafından yapılandırılabilir ve genellikle wp-config.php tanımlanır. Bu durumda base_prefix kullanıyoruz çünkü tüm cli oturum açma işlemleri (kullanıcılar gibi) için yalnızca tek bir tablo oluşturuyoruz. Çok siteli kurulumlarda, $wpdb->prefix mevcut sitenin önekinde blog kimliğini içerecektir (yani wp_2_ , wp_99_ , vb.) burada base_prefix ne olursa olsun her zaman ana siteyle (yani wp_ ) aynı olacaktır. güncel site. Tek sitede base_prefix ve prefix her zaman aynı olacaktır. Özel tablonuz siteye özel veriler içerecekse, tablonun çoklu sitedeki her alt site için oluşturulmasını sağlamak için prefix kullanmalısınız.
dbDelta işlevi ayrıca, ona ilettiğiniz SQL ifadesinin birkaç ekstra kurala uymasını gerektirir. Aksi takdirde geçerli SQL'in işlevin ayrıştırma ve doğrulamasında başarısız olmasına neden olacağından bunların gözden geçirilmesi önemlidir.
UYARI: FONKSİYONA DOĞRUDAN BAKMAYIN. (kaynak)

Benim yaptığım gibi tabloyu oluştururken karşılaşabileceğiniz bir sorun şu şekilde bir hatadır:
WordPress database error Specified key was too long; max key length is 767 bytes for query
Bu, bir varchar veya tinytext sütunu için maksimum uzunluk 255'i belirtirken alacağınız bir hatadır. Bu bayt cinsinden bir sınırlama olduğundan, tablonun karakter kümesine bağlı olarak maksimum uzunluk farklıdır. Gary Pendergast (aka @pento) kaynakta şöyle açıklıyor:
/* * Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that. * As of 4.2, however, we moved to utf8mb4, which uses 4 bytes per character. This means that an index which * used to have room for floor(767/3) = 255 characters, now only has room for floor(767/4) = 191 characters. */ $max_index_length = 191; // wordpress/wp-admin/includes/schema.php
Artık özel tablomuzu oluşturacak kodumuz olduğuna göre, onu ne zaman ve nerede çalıştıracağız? Yükseltme rutinini girin.

Yükseltme Rutini Oluşturma
Yükseltme rutini, bir sistemin durumunu eski bir sürümden daha yenisine güncellemek için tasarlanmış bir işlemdir. Büyük sürümler arasında bir veritabanı güncellemesi isteyen WordPress'in kendi ekranını muhtemelen biliyorsunuzdur:

Bir yükseltme rutininin, veritabanı üzerinde bir işlem gerçekleştirmeye özel olması gerekmez, ancak bu belki de en yaygın kullanım durumudur. İki temel bölümden oluşur: bir tetikleyici ve süreç(ler).
Tetikleyici genellikle, belirli bir istek yaşam döngüsünün başlarında, yükte veya belirli bir kancada çalışabilen basit bir sürüm denetimidir. Veritabanından mevcut veritabanı sürümünüzü alın (WordPress çekirdeği, veritabanı sürüm numarasını db_version seçeneğinde saklar; bunu değiştirmeyin), bunu yüklenen eklentinin/temanın sürümüyle vb. karşılaştırın. Kaydedilen sürüm, yüklü sürüm, yükseltme rutini ile devam edin ve bittiğinde kayıtlı veritabanı sürümünü güncelleyin. Bu en temel mantıktır, ancak birden fazla varsa hangi rutinin daha sonra çalışacağını kontrol ederken ek kontroller gerekli olabilir.
WordPress'in sürüm işlemesini kendi seçeneğimizle modelleyeceğiz ve sadece veritabanı sürümümüz için basit bir tamsayı saklayacağız.
namespace WP_CLI_Login; function upgrade_200($wpdb) { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE `{$wpdb->base_prefix}cli_logins` ( public_key varchar(191) NOT NULL, private_key varchar(191) NOT NULL, user_id bigint(20) UNSIGNED NOT NULL, created_at datetime NOT NULL, expires_at datetime NOT NULL, PRIMARY KEY (public_key) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); $success = empty($wpdb->last_error); return $success; } function upgrade() { $saved_version = (int) get_site_option('wp_cli_login_db_version'); if ($saved_version < 200 && upgrade_200()) { update_site_option('wp_cli_login_db_version', 200); } }
Yukarıdaki kodda, \WP_CLI_Login\upgrade() işlevinin çağrılması, uygulanmamış tüm yükseltmeleri çalıştıracaktır. Şu anda bu sadece bir tanesidir, ancak gelecekte daha fazlasını koymak için bir yer verir.
Yükseltmeyi Çağırma
Yükseltme rutininin ne zaman çalıştığının önemi, büyük ölçüde yükseltmeye ve ne yapacağına bağlı olacaktır. Bu, PHP'nin eşzamanlı doğası nedeniyle özellikle önemlidir; ne kadar süreceğine dikkat etmeliyiz. Bu durumda, bir tablo oluşturmak önemsiz bir zaman olduğundan endişelenecek fazla bir şey yok – ama ne zaman yapmalı? Bu, oturum açmaların saklanma şeklini temelden değiştireceğinden, yeni bir oturum açma oluşturulmadan önce gerçekleşmesi gerekir. Komuttaki kod, yeni tabloyu kullanmak için değiştirilecektir, bu nedenle yükseltme, kaydı özel tabloya eklemek için veritabanı sorgusunu çalıştırmazsa, yükseltme çalışana kadar tablo olmadığı için patlayacaktır.
WordPress, wp-admin/admin.php her yükünde dahili veritabanı sürümünü kontrol eder. Kaydedilen veritabanı sürümü, tanımlanan mevcut sürümden ( wp-includes/version.php içinde tanımlanan) daha düşükse, yukarıdaki yükseltme ekranına yönlendirilirsiniz. Çoğu eklenti, kullanıcıyı veritabanını güncellemek için böyle bir engelleme sürecinden geçmeye zorlamaz, ancak bunu yapmak kullanıcıya örneğin önce veritabanını yedekleme şansı verir. İşleri bu şekilde yapmak, yeni kodunuzun eski yöntemle geriye dönük olarak uyumlu olmasını da gerektirir. Bu tür bir işlem, kullanıcının herhangi bir şey yapmasına gerek kalmadan tamamen arka planda da çalışabilir.
Bu durumda, komut sınıfı, yeni bir oturum açma oluşturulmadan önce çalıştırılan, ensurePluginRequirementsMet adlı bir yönteme zaten sahiptir. Bu, şu anda yardımcı sunucu eklentisinin kurulu olup olmadığını ve sürümünün komutun gerektirdiği sürümü karşılayıp karşılamadığını kontrol eder. Olmazsa, komut, kurulu eklentinin nasıl güncelleneceğine ilişkin talimatlarla (başka bir komutla!) hata verir. Bu, veritabanının güncel olup olmadığını kontrol etmek ve gerekirse yükseltmek için mükemmel bir yer gibi görünüyor.
Bunun çalıştırılabileceği diğer birkaç yer:
- Yardımcı eklentinin login komutuyla yüklenmesi üzerine
- Bir eklenti etkinleştirme kancası kullanarak tamamlayıcı eklentinin etkinleştirilmesi üzerine
Bir eklenti yükseltildiğinde eklenti etkinleştirme kancalarının çağrılmadığını unutmayın -
admin_initeylemine bağlı her wp-admin isteği (WordPress çekirdeğine benzer) -
plugins_loadedveyainiteylemlerine bağlı her istek
Bitirmek
Son adım, daha önce geçici olarak depolanan verileri yükleyen ve kaydeden komuttaki mevcut kodu güncellemektir. Bu işlemlere kendi yöntemleri verildiğinden, değiştirilmesi gereken yalnızca bir avuç kod bloğu vardır.
Her değişikliği gözden geçirmeyeceğim, ancak kodun geçici bir durum kullanmak yerine yeni bir veritabanına yeni bir oturum açmayı kaydetmek için nasıl değiştiği aşağıda açıklanmıştır.
Önce
private function persistMagicUrl(MagicUrl $magic, $endpoint, $expires) { set_transient( self::OPTION . '/' . $magic->getKey(), json_encode($magic->generate($endpoint)), ceil($expires) ); }
Sonrasında
private function persistMagicUrl(MagicUrl $magic, $endpoint, $expires) { global $wpdb; $data = $magic->generate($endpoint); $wpdb->insert("{$wpdb->base_prefix}cli_logins", [ 'public_key' => $magic->getKey(), 'private_key' => $data['private'], 'user_id' => $data['user'], 'created_at' => gmdate('Ymd H:i:s'), 'expires_at' => gmdate('Ymd H:i:s', $data['time'] + ceil($expires)), ]); }
Kapanış Düşünceleri
WordPress, verilerimizi sürdürmenin birkaç yolu ile birlikte gelir. Çoğu durumda bunlar fazlasıyla yeterli ve onlarla çok şey yapılabilir. Bir çözümden diğerine geçme ihtiyacı ortaya çıkarsa, bununla başa çıkmak için bir yükseltme rutini yazabiliriz.
Özel bir tablo kullanmanın iş için doğru araç olabileceği birkaç durum aşağıda verilmiştir:
- Depolanacak veriler, bir gönderi, terim, kullanıcı, seçenek veya meta veri olarak depolamak için kavramsal olarak iyi uymuyor
- Veriler "sorgulanabilirlik" için serileştirilemez
- Bir çekirdek tabloda ihtiyaç duyulan satır sayısı kolayca 10 binlere veya daha fazlasına ulaşabilir.
- Veriler, performans için son derece özelleştirilmesi gereken karmaşık sorgulara tabi olacaktır.
Faydaların, gerekli ekstra tablo(lar)ı oluşturma ve sürdürme işine ek olarak, kancalar ve önbelleğe alma gibi hazır WordPress çözümleriyle ücretsiz olarak elde ettiğimiz bazı şeylerin pahasına olduğunu unutmayın. Yine de hata yapmayın, konu güç ve esneklik olduğunda, sizin özel ihtiyaçlarınız için oluşturulmuş ve ayarlanmış iyi tasarlanmış bir şema ve API'den daha iyi bir şey olamaz.
Eklentiniz veya temanız özel bir tablo kullanıyor mu? Favori (veya en az favori) eklentiniz veya temanız var mı? Sizin için nasıl çalıştı? Acılar nelerdi, sevinçler nelerdi? Aşağıdaki yorumlarda bize bildirin!
ev borcu WordPress sitesi