PHP bit bayrakları için en iyi uygulamalar

7 Cevap php

PHP + MySQL küçük bir uygulama writng yaşıyorum ve onunla ilişkili bayrakları (8 şimdiye kadar ama değil artması bekleniyor) bir çift olan bir nesne olduğu noktaya gelmiş. Hiçbir mantıklı olur bazı kombinasyonlar olsa bayraklar oldukça fazla ilgisiz. Nesnesi, bir DB satır temsil (çok yüklemeden / tasarrufu için bazı yöntemler vardır) böylece soru aynı zamanda bir depolama yöntemi seçerek için geçerlidir.

Soru - how to best represent them both in code and DB? Ben çeşitli şekillerde düşünebilirsiniz:

DB bunları saklamak için bir yoldur bit bayrakları gibi tek tamsayı alanında. PHP tarafında sonra bunları temsil eden çeşitli yollar hayal edebiliyorum:

  • Sadece tamsayı değeri vermek ve bayrak sabitleri bir çift var; Bayraklar kendi bit büyü yapmak gerekiyor her yer olsun;
  • Sınıfı yöntemlerini tanımlayın GetFlag(), SetFlag() ve UnsetFlag() Bu özel bir tamsayı değişken üzerinde bitsel büyü yapmak; Bu yöntemler daha sonra bir parametre olarak bayrak sabitleri biri geçti olacaktır.
  • (Set ve Unset meslektaşları ile birlikte) yöntemleri GetFlagA(), GetFlagB() vb tanımlayın;
  • Her biri bayrağı temsil eden üye değişkenler bir grup tanımlayın; DB yükleme onları ayarlayın ve kaydederken onları toplamak.
  • Tüm bayrak değerleri dizisi olan bir üye değişkeni oluşturun. Her bayrak erişmek için dizi indeksleri olarak önceden tanımlanmış sabitleri kullanın. Ayrıca yükleme / tasarrufu diziyi toplamak / doldurun.

Başka bir yol, ayrı BIT alanlar olarak DB bunları saklamak olacaktır. PHP sonra birkaç üye değişkenleri çevirmek söyledi. IMHO bu sorguları zorlaştıracaktır.

Ve son yolu bayraklar ve orijinal nesneler arasında çok-çok ilişkisi için tüm bayrakları ve bir ara tablo için anothed tablo tanımlamak olacaktır. IMHO tüm çözümleri messiest, aksi takdirde sadece 3 tablolar gibi olacağını düşünüyor.

Ben bu yüzden en iyi yöntem ne olacağını bilmiyorum çok PHP geliştirme yapmadım. C # Ben muhtemelen onları gibi bitsel bayrakları saklamak ve özel bir tamsayı üzerinde bitsel büyü yapmak özelliklerini yapacak. Ama PHP (ben son kararlı sürümünü kullanıyorum) özelliklerine sahip değildir ...

7 Cevap

Da model, nesne 8 boolean özellikleri vardır. Bu veritabanı tablosundaki 8 boolean (MySQL için TINYINT) sütunlar ve nesne 8 alıcı / ayarlayıcı yöntemleri anlamına gelir. Basit ve geleneksel.

Geçerli yaklaşım yeniden düşünmek. Bu şeyi korumak zorundadır sonraki adam söyleyerek ne olacağını düşünün.

CREATE TABLE mytable (myfield BIT(8));

Biz Buradaki bazı ikili veriler için gidiyoruz gibi Tamam, görünüyor.

INSERT INTO mytable VALUES (b'00101000');

Biri bu 1s ve 0s her açılımı ne tekrar söyle, bekleyin.

SELECT * FROM mytable;
+------------+
| mybitfield |
+------------+
| (          | 
+------------+

Ne?

SELECT * FROM mytable WHERE myfield & b'00101000' = b'00100000';

WTF!? WTF!?

stabs self in face


- Bu arada, periler tek boynuzlu at ve programcılar ile oynayacak alternatif bir evrende DBA'ların nefret etmiyorum ... -

SELECT * FROM mytable WHERE field3 = 1 AND field5 = 0;

Mutluluk ve güneş!

Eğer gerçekten bit bayrakları kullanmak varsa, o zaman DB, kodda bir ilişkisel dizi bunları saklamak için bir SET sütun kullanabilirsiniz, ve yöntemler / kapalı bayrakları açmak için. Eğer bu formatta gerekiyorsa bir tek tamsayı için / dizi dönüştürmek için ayrı yöntem ekleyin.

Orada düşük seviyeli bit operatörleri kullanılarak elde edilecek bir şey yok, bu yüzden de kod okunabilir hale olabilir.

Tamam, bu konuda biraz daha düşündükten sonra, ben bayrak başına bir üye değişkeni ile gitmeye karar verdik. Ben alıcı / ayarlayıcı yöntem yaklaşımı kullanmış olabilir, ama ben bu yüzden bu out-of-tarzı olurdu benim kodunda onları başka bir yerde kullanmayın. Artı, ben de uzak DB depolama yöntemi soyut ve bu şekilde daha sonra kolayca değiştirebilirsiniz gerekirse.

DB gelince - ben şimdi bit tamsayı ile kalmak için gidiyorum - Ben neredeyse yazılımı ile bitti ve o artık değiştirmek istemiyorum çünkü. Hiç de okunabilirliği değişmez.

PHP ve MySQL enums arasındaki boşluğu doldurmak için bu basit işlevi kodlu:

function Enum($id)
{
    static $enum = array();

    if (func_num_args() > 1)
    {
        $result = 0;

        if (empty($enum[$id]) === true)
        {
            $enum[$id] = array();
        }

        foreach (array_unique(array_map('strtoupper', array_slice(func_get_args(), 1))) as $argument)
        {
            if (empty($enum[$id][$argument]) === true)
            {
                $enum[$id][$argument] = pow(2, count($enum[$id]));
            }

            $result += $enum[$id][$argument];
        }

        return $result;
    }

    return false;
}

Kullanımı:

// sets the bit flags for the "user" namespace and returns the sum of all flags (15)
Enum('user', 'anonymous', 'registed', 'active', 'banned');

Enum('user', 'anonymous'); // 1
Enum('user', 'registed', 'active'); // 2 + 4 = 6
Enum('user', 'registed', 'active', 'banned'); // 2 + 4 + 8 = 14
Enum('user', 'registed', 'banned'); // 2 + 8 = 10

Sadece emin MySQL ENUM aynı sırayla numaralandırılmış liste tanımlamak yapmak zorunda.

Senin sen [number of bits here] BIT olarak sütun tanımlayabilirsiniz 5.0.5 sonra MySQL bir sürümünü kullanarak varsayarsak. Herhalde Get / SetFlagA, Get / SetFlagB yaklaşımı ile gitmek istiyorum PHP tarafında gelince, sadece set yöntemi bir mantıksal almak gibi bir tanımsız yöntemine gerek yoktur.

O bayrakları (Nedense süper verimli olması için çalıştığınız sürece) veritabanına sadece bakarak ayarlanır hangi bilmek çok zor olur gibi uzak bitsel faaliyetlerinden uzak kalmak istiyorum. Diğer iki seçenek arasında ben bu bayrakların her ne kadar anlamı üzerinde bağlıdır düşünüyorum. 8 tanesi zaten var olduğu göz önüne alındığında ben (sizin en sevdiğiniz toplamak için özür dilerim) bunların arasında birçok ilişki için bir çok başka masaya doğru yalın olacaktır.

One way to store them in the DB is in a single integer field as bitwise flags.

Bunu yapmak istedim, __ get ve __ set overload methods kullanmak böylece sadece alanını almak, ve sonra gerektiği gibi bit aritmetik işlemler yapabilir.