Türkiye Online Medya Araştırması
Profili Göster

PHP Tip Güvenliği

Hakan DAMAR Tarih: 13/06/2009 Yorum: 3 adet

Okunma : 2333 Tutanlar: Bu yazıyı 2 kişi tuttu.

Merhaba,

Bildiğiniz üzere PHP , C# gibi type güvenliği olan dillerden değildir. Değişkenler tipi belirtilmeden yaratılır ve ona göre kullanılır. Peki tip güvenliği dedimiz olay nedir?

Tip güvenli bir değişken oluşturalım.


[C#]
int sayi = 1535;
float fSayi = 15.4;
string yazi = "Microsoft Windows 7″;

Tip güvenliği olmadan oluşturalım.


[PHP]
$sayi = 1535;
$fSayi = 14.45;
$yazi = "I lost control. :)";

Şimdi bu iki tanımlama arasındaki fark sizinde tahmin ettiğiniz gibi birisinde oluşturulan değişkenin tipi baştan belirtilerek oluşturuluyor böylece ileride kullandığımızda programımız her birini tipine uygun çalıştırıyor veya hata veriyor. Diğerinde ise tip belirtmeden bunu dilin kendisinin anlamasını tercih ediyoruz. Gerçi PHP 5.2.x sürümünden sonra bu ayrımı çok daha iyi yapıyor fakat büyük programlarda tür dönüşümleri ve değer tip değişikliklerinden çok büyük problemler çıkabilmektedir.

Peki PHP bunun için ne yapıyor? Tabii ki bir çözümümüz var. Yukarıdaki aynı tanımlamayı şu şekilde de yapabiliriz.


[PHP]
$sayi = (int)1535;
$fsayi = (double)14.45;
$yazi = (string)"I lost control";

Böylece hem değişken tanımlamış hem de aynı zamanda bir convert işlemi ile değişkenlerin türlerini istediğimiz türe çevirdik. PHP ile değişken tanımlama seviyesinde yapabileceğimiz maximum budur diye tahmin ediyorum. Peki biz önemli projelerimizde bu tipleri nasıl kontrol edeceğiz. Büyük bir program geliştirdiğimizde, değişkenin nerelerden geçtiğini ve son değişken değerinin, bizim istediğimiz tipten olup olmadığını anlamak güçtür. Ayrietten bunu run time'da denetlemek daha da zordur. Çünkü, gelen veriler kullanıcılardan veya farklı 3. bir web servisinden olabilir. Bu nedenle bizim bunu program içinde denetlememiz gerekmektedir. Böylece runtime'da gelen datalar kontrol fonksiyonu tarafından denetlenerek olası problemler öngörülecektir.

İlgili fonksiyonu aşağıda veriyorum. Kendi class'larınıza ekleyebilirsiniz.


<?php
class foo {
        protected $type;
        /**
         * Type Controller
         *  @var any type
         */
        public function typeControl($type) {
                $this->type = $type;
                is_string($type) ? $type = "String" : null;
                is_int($type) ? $type = "Int" : null;
                is_double($type) ? $type = "Double" : null;
                is_bool($type) ? $type = "Bool" : null;
                is_array($type) ? $type = "Array" : null;
                is_float($type) ? $type = "Float" : null;
                is_object($type) ? $type = "Object" : null;
                $type = "Bu değişken ".$type." türündendir.<br>";
                return print $type;
        }
}

// Variables
$control = new foo();
$int = 3;
$str = "test";
$double = 7.9;
$bool = false;
$arr = array("Hakan",9,"Arda",7,"Atilla",3);
$object = new foo();

// Type Controller
$control->typeControl($bool);
$control->typeControl($double);
$control->typeControl($str);
$control->typeControl($int);
$control->typeControl($arr);
$control->typeControl($object);
?>

İyi Çalışmalar.

Hakan DAMAR

aç-kapa İçeriğin rss beslemesi kullanımda değil Yorumlar

Profili Göster
Selcuk.Bozdag 15/06/2009

dinamik-statik dil tartismasina girmek istemiyorum ama dinamik bir dilde eger degisken turu tanimlamak gerekmiyorsa, bence bunun guvenli olmadigini o andan sonra "sorgulamamak" lazim diye dusunuyorum.

benim sormak istedigim iki sey var.

birincisi bu yazdigin metodu sadece primitif turler icin yazmadan butun siniflar ve kullanici tanimli siniflar icin nasil yazardin?

ikincisi, PHP'de varolan gettype(), get_class() metodlarindan yararlanarak tur denetimi yapmak daha iyi degil mi? (illaki yapmak gerekiyorsa ki ben bunu gereksiz goruyorum hala)

makale icin tesekkurler.

Profili Göster
Hakan DAMAR 21/06/2009

Öncelikle okumak için zaman ayırdığından dolayı teşekkür ediyorum.

Büyük uygulamalarda tip kontrolü olmadan ilerlediğimde hep başıma bu tip değişikliklerinden sorun çıkmıştır. Yazdığımızda o an bir sorun yok. Sorunsuz çalışıyor fakat senkron iş yapan class'lar bir birlerine veri aktardıklarında atıyorum $int_logRows; değişkeni bir anda 102.1 değeri gelerek int'ten double'a dönebiliyor. Belki çoğu uygulamada olmaz ama finans modülü olan bir uygulamada her türü tek bir değer tipi döndürmeye zorlamayamıyoruz ( Örn: intval() ). Eğer böyle bir convert işlemi yaparsak küsüratları kaybedebiliriz.

PHP'nin source kodlarından gettype() fonksiyonunu incelemedim ama php.net'te yazılana göre bu fonksiyonu kritik karşılaştırmalarda kullanmamamızı söylüyorlar ve yavaş olduğunuda belirtiryorlar. Bu açıklamayı yaptıktan sonra madem düzgün çalışmıyor ve yavaş, neden yazıldığını sorguladım. :) İlgili Açıklama: http://us3.php.net/manual/en/function.gettype.php

Diğer class'lar için ya bir interface'in içine gömerdim. Yada main class'lardan birine(Base'de implimente edilen.) protected olarak yazardım.

Saygılarımla.

Profili Göster
Fırat Ağdaş 6/10/2009

Makale için teşekkürler...

Ben de bu noktada veri tiplerinin çağırılması gibi sınıfa ihtiyaç duymadım.

Mesela diyelim ki girilen veri:

$degisken = '2';

Benim ise ihtiyacım olan tam sayı 2... Pekala bunun için sırf

if ($control->typeControl($degisken) != 'int') { triggererror('Geçersiz veri tipi', EUSER_ERROR); }

Biraz saçma olabilirdi :) Bunun yerine ihtiyacımız olan o veri tipine zorlamak daha mantıklı... Mesela bu başlık için basit bir sınıf yazdım...


<?php

class Datatype_Forcing
{
    const FORCE_STR = 1;
    const FORCE_INT = 2;
    const FORCE_FLOAT = 4;
    const FORCE_BOOL = 8;
    const FORCE_ARRAY = 16;

    /*

    İstenildiği taktirde Uzatılabilir....

    const FORCE_UINT = 16; // Doğal Sayı (0 ve 0 'dan Büyük Tam Sayılar)
    const FORCE_MD5 = 32; // MD5 olması zorunlu string ^[a-f0-9]{32}$
    .
    .
    .
    .
    .
    vs. vs..

    */


    public function __construct()
    {
        // doğrudan oluşturulamaz sınıf
    }

    public function apply($data, $forcetype = self::FORCE_STR)
    {
        if (!$this->verify_forcetype($forcetype))
        {
            trigger_error('Datatype_Forcing::force() fonksiyonu için geçersiz zorlama tipi', E_USER_ERROR);
        }

        switch (true)
        {
            case (($forcetype & self::FORCE_ARRAY) == self::FORCE_ARRAY):
                $data = is_array($data) ? $data : array();
                $forcetype = $forcetype = $forcetype & ~self::FORCE_ARRAY;

                // Dizi değerleri içinde kısa yoldan doğrulama?
                if (!empty($data) AND $forcetype > 0)
                {
                    foreach ($data AS $key => $subdata)
                    {
                        $data["$key"] = $this->apply($subdata, $forcetype);    
                    }
                }
            break;

            case (($forcetype & self::FORCE_STR) == self::FORCE_STR):
                $data = trim(strval($data));
            break;
            case (($forcetype & self::FORCE_INT) == self::FORCE_INT):
                $data = intval($data);
            break;
            case (($forcetype & self::FORCE_FLOAT) == self::FORCE_FLOAT):
                $data = floatval($data);
            break;
            case (($forcetype & self::FORCE_BOOL) == self::FORCE_BOOL):
                $data = !empty($data) ? 1 : 0;
            break;
        }

        return $data;
    }

    public function verify_forcetype($forcetype)
    {
        // tip içerisinde FORCE_ARRAY mevcutse çıkar...
        if ($forcetype & self::FORCE_ARRAY)
        {
            $forcetype = $forcetype & ~self::FORCE_ARRAY;
            if (empty($forcetype))
            {
                return true;
            }
        }

        return in_array($forcetype, array(self::FORCE_STR, self::FORCE_INT, self::FORCE_FLOAT, self::FORCE_BOOL));
    }
}

$force =& new Datatype_Forcing();

$test1 = '   Test 1    ';
$test2 = '26.1';
$test3 = false;
$test4 = array(
    '   sdf asdf ',
    '12',
    16.5
);

echo "
<style type=\"text/css\"> html { font: 10pt Verdana } </style>

Karakter Testleri <br /><p>";

echo "Test1: " . $force->apply($test1, Datatype_Forcing::FORCE_STR) . "<br />\n";
echo "Test2: " . $force->apply($test1, Datatype_Forcing::FORCE_INT) . "<br />\n";
echo "Test3: " . $force->apply($test1, Datatype_Forcing::FORCE_FLOAT) . "<br />\n";
echo "Test4: " . print_r($force->apply($test1, Datatype_Forcing::FORCE_ARRAY), true) . "<br />\n";
echo "Test5: " . $force->apply($test1, Datatype_Forcing::FORCE_BOOL) . "</p>\n";


echo "Tam Sayı Testleri <br /><p>";

echo "Test1: " . $force->apply($test2, Datatype_Forcing::FORCE_STR) . "<br />\n";
echo "Test2: " . $force->apply($test2, Datatype_Forcing::FORCE_INT) . "<br />\n";
echo "Test3: " . $force->apply($test2, Datatype_Forcing::FORCE_FLOAT) . "<br />\n";
echo "Test4: " . print_r($force->apply($test2, Datatype_Forcing::FORCE_ARRAY), true) . "<br />\n";
echo "Test5: " . $force->apply($test2, Datatype_Forcing::FORCE_BOOL) . "</p>\n";

echo "Reel Sayı Testleri <br /><p>";

echo "Test1: " . $force->apply($test3, Datatype_Forcing::FORCE_STR) . "<br />\n";
echo "Test2: " . $force->apply($test3, Datatype_Forcing::FORCE_INT) . "<br />\n";
echo "Test3: " . $force->apply($test3, Datatype_Forcing::FORCE_FLOAT) . "<br />\n";
echo "Test4: " . print_r($force->apply($test3, Datatype_Forcing::FORCE_ARRAY), true) . "<br />\n";
echo "Test5: " . $force->apply($test3, Datatype_Forcing::FORCE_BOOL) . "</p>\n";

echo "Dizi Testleri <br /><p>";

echo "Test1: " . $force->apply($test4, Datatype_Forcing::FORCE_STR) . "<br />\n";
echo "Test2: " . $force->apply($test4, Datatype_Forcing::FORCE_INT) . "<br />\n";
echo "Test3: " . $force->apply($test4, Datatype_Forcing::FORCE_FLOAT) . "<br />\n";
echo "Test4: " . print_r($force->apply($test4, Datatype_Forcing::FORCE_ARRAY), true) . "<br />\n";
echo "Test5: " . $force->apply($test4, Datatype_Forcing::FORCE_BOOL) . "</p>\n";

echo "Dizi-Karakter Testleri <br /><p>";

echo "Test4: " . print_r($force->apply($test4, Datatype_Forcing::FORCE_ARRAY | Datatype_Forcing::FORCE_STR), true) . "<br />\n";

echo "Dizi-Tam sayı Testleri <br /><p>";

echo "Test4: " . print_r($force->apply($test4, Datatype_Forcing::FORCE_ARRAY | Datatype_Forcing::FORCE_INT), true) . "<br />\n";

echo "Dizi-Reel Sayı Testleri <br /><p>";

echo "Test4: " . print_r($force->apply($test4, Datatype_Forcing::FORCE_ARRAY | Datatype_Forcing::FORCE_FLOAT), true) . "<br />\n";


?>

Çıktı Sonucu




<style type="text/css"> html { font: 10pt Verdana } </style>

Karakter Testleri <br /><p>Test1: Test 1<br />
Test2: 0<br />
Test3: 0<br />
Test4: Array
(
)
<br />
Test5: 1</p>
Tam Sayı Testleri <br /><p>Test1: 26.1<br />
Test2: 26<br />
Test3: 26.1<br />
Test4: Array
(
)
<br />
Test5: 1</p>
Reel Sayı Testleri <br /><p>Test1: <br />
Test2: 0<br />
Test3: 0<br />
Test4: Array
(
)
<br />
Test5: 0</p>
Dizi Testleri <br /><p>Test1: Array<br />
Test2: 1<br />
Test3: 1<br />
Test4: Array
(
    [0] =>    sdf asdf 
    [1] => 12
    [2] => 16.5
)
<br />
Test5: 1</p>
Dizi-Karakter Testleri <br /><p>Test4: Array
(
    [0] => sdf asdf
    [1] => 12
    [2] => 16.5
)
<br />
Dizi-Tam sayı Testleri <br /><p>Test4: Array
(
    [0] => 0
    [1] => 12
    [2] => 16
)
<br />
Dizi-Reel Sayı Testleri <br /><p>Test4: Array
(
    [0] => 0
    [1] => 12
    [2] => 16.5
)
<br />

Böylece veri tipi kontrolü yapmaktansa veriyi her ne olursa olsun istediğimiz veri tipine zorlayabilir ve geçerli aralıklarla olup olmadığını doğrulayabiliriz. Dolayısıyla işlemleri yarıda kesmemiş oluruz. Bana göre bu şekilde bir yönlendirme daha mantıklı olacaktır.

Kolay gelsin.

aç-kapa Yazarın Diğer Yazıları

yeni üyelik | şifremi unuttum

aç-kapa Toplantı Özgür Yazılım ve Linux Günleri '10

Özgür Yazılım ve Linux Günleri '10

İstanbul Bilgi Üniversitesi Bilgisayar Bilimleri Bölümü ve Linux Kullanıcıları Derneği'nin 9 yıldır düzenlemekte oldukları etkinlikler bu yıl `Özgür Y...
Kategori: Toplantı

aç-kapa Yarışma 3. Uluslararası Ekslibris Yarışması: İstanbul 2010

3. Uluslararası Ekslibris Yarışması: İstanbul 2010

İstanbul Ekslibris Dernegi, Feyziye Mektepleri Vakfı ve Işık Üniversitesi, kitaplar için mülkiyet işareti olarak kabul edilen ve üzerinde estetik dege...
Kategori: Yarışma

aç-kapa Konferans Yeni Medya ve Etkileşim Konferansı 2010 - Marmara Üniversitesi

Yeni Medya ve Etkileşim Konferansı 2010 - Marmara Üniversitesi

Generally speaking, the term "New" brought about debates. We try to open up and elucidate the term "New" along with "Interact...
Kategori: Konferans

aç-kapa Konferans 3. Uluslararası Gelecek İçin Öğrenme Alanında Yenilikler Konferansı 2010: e-Öğrenme

3. Uluslararası Gelecek İçin Öğrenme Alanında Yenilikler Konferansı 2010: e-Öğrenme

Konferans ile ilgili ayrıntılı bilgiye aşağıdaki bağlantıdan ulaşabilirsiniz: http://www.futurelearning.org.tr/katilim_cagrisitr.pdf ...
Kategori: Konferans

üyeler Son Kahramanlar...

stats Kimler Burada? web stats

Son 1 dakika içinde MMIstanbul' da 54 (50 kayıtlı, 4 ziyaretçi) kullanıcı varmış. Login durumda olanlar aşağıda:

...

Blog Bölümü Blogevi.com'a Taşınıyor

Selam arkadaşlar MMIstanbul'da , tasarımcı ve programcıların blog yazılarını "feedleyerek" MMIstanbul okurlarını MMIstanbul dışın ...

7.500'üncü üyemiz Cem Koç!

Neler Yapılabilir?

500 Hatası Hakkında!

Reklam, MMIstanbul ve Yeni Projeler (Durumumuz Bu Tarzında)

coldfusion mysql ubuntu
 
sponsor adobe istanbul