Ne) (özü ile bu kadar yanlış?

11 Cevap php

I was recently reading this thread, on some of the worst PHP practices. In the second answer there is a mini discussion on the use of extract(), and im just wondering what all the huff is about.

Ben şahsen böyle bir $ _GET ya da uygun benim için adını almış gibi Sonra, sonra değişkenleri dezenfekte nerede $ _POST olarak verilen bir dizi kıymak için kullanabilirsiniz.

Bu kötü bir uygulama mı? Risk burada nedir? Ekstresinin kullanımı () hakkında düşünceleriniz nelerdir?

Teşekkür ederim,

11 Cevap

Ben (bir kaç hafta ya da kendinizi) gelecekteki bakıcılarına geldiklerini hiçbir fikrim yok değişken bir dizi neden olabilir ki o sadece kötü bir uygulama olduğunu bulmak. Bu senaryoyu düşünün:

extract($someArray); // could be $_POST or anything

/* snip a dozen or more lines */

echo $someVariable;

$someVariable nereden geldi? Herkes nasıl söyleyebilir?

Ben onlar başlayan dizi içinde değişkenleri erişimde sorun görmüyorum, bu yüzden gerçekten for extract() Bana bu kadar düşünmek için kullanan iyi bir olguyu sunmak gerekiyordu buna değer. Bazı ekstra karakterleri yazarak gerçekten endişe ediyorsanız o zaman sadece bunu:

$a = $someLongNameOfTheVariableArrayIDidntWantToType;

$a['myVariable'];

Ben burada bunun güvenlik yönleri üzerinde bir yorum biraz solmuş düşünüyorum. Fonksiyonu (aslında size (EXTR_SKIP), SADECE mevcut değişkenleri yazılmadan (böylece bir beyaz liste oluşturabilirsiniz) herhangi bir mevcut değişkenleri değil üzerine de dahil olmak üzere yeni oluşturulan değişkenler üzerinde oldukça iyi kontrol sağlayan ikinci bir parametre alabilir { [(1)]}) veya değişkenlere önek (EXTR_PREFIX_ALL).

risk: kullanıcıların veri güven ve simge tablosuna dahil ayıklanması sizin değişkenleri kullanıcı sağlayan bir şey tarafından üzerine olabilir, gelir yok.

<?php
    $systemCall = 'ls -lh';
    $i = 0;

    extract($_GET);

    system($systemCall);

    do {
        print_r($data[$i];
        $i++;
    } while ($i != 3);

?>

(A saçma örnek)

ama şimdi kodunu tahmin veya bilen kötü niyetli bir kullanıcı çağırır:

yourscript.php?i=10&systemCall=rm%20-rf

yerine

yourscript.php?data[]=a&data[]=b&data[]=c

Şimdi, $ systemcall ve $ i komut önce verilerinizi silme ve ardından asılı sonuçlanan yazılır.

Hadi şimdi. İnsanlar aracı yerine kullanıcıyı suçlarlar.

Onunla dosyaları silebilirsiniz çünkü () unlink karşı konuşmak gibi. extract () diğer herhangi bir gibi bir işlevi olduğunu, akıllıca ve sorumlu bir şekilde kullanın. Ama bu sadece cahil, öyle başına kötü iddia etmiyorum.

Dikkatlice kullanılmadığı takdirde dikkate çalışmak diğerleri dışarı halt karıştırmayın olabilir:

<?php

    $array = array('huh' => 'var_dump', 'whatThe' => 'It\'s tricky!', 'iDontGetIt' => 'This Extract Function');
    extract($array);
    $huh($whatThe, $iDontGetIt);


?>

Verim:

string(12) "It's tricky!"
string(21) "This Extract Function"

Bir şaşırtmaca kullanmak yararlı olacaktır. Ama unutamıyorum "Nerede bu var nereden geldi?" Ben çalıştırmak sorunu.

O potential kötüye zorundadır çünkü insanlar her yukarı-silah özü hakkında olsun. Ekstraktı ($ _POST) gibi bir şey yapmak size ne yaptığınızı biliyorsanız bile, her durumda iyi bir fikir değildir. Ancak, bir görünüm şablon veya benzer bir şey için değişkenleri açığa gibi şeyler yapıyorsun zaman kullandığı oluyor var. Temelde, sadece bunu yapmak için iyi bir neden olması çok belli olduğunda kullanmak ve buna $ _POST şey deli gibi geçen fikir alırsanız özü tipi parametresini nasıl kullanılacağını anlamak.

Ben bir sürü insan bunu kullanmanızı tavsiye etmiyoruz nedeni (hatta $_REQUEST) superglobals $_GET ve $_POST ayıklanması ile genel ad değişkenleri kaydeder olduğunu tahmin temelde register_globals öykünen bu diziler içinde her tuşu gibi aynı ad = 1.

Ben PHP manual Benim için konuşuyorum izin vereceğim.

Arka Plan: extract($_REQUEST) register_globals = On php.ini ayarı olarak aynı

Eğer bir fonksiyonu ayıklamak ise, değişkenler sadece bu kapsamda satışa sunulacak. Bu genellikle görünümler kullanılır. Basit bir örnek:

//View.php
class View {
    function render($filename = null) {
    	if ($filename !== null) {
    		$this->filename = $filename;
    	}
    	unset($filename);
    	extract($this->variables);
    	ob_start();
    	$this->returned = include($this->dir . $this->filename);
    	return ob_get_clean();
    }
}

//test.php
$view = new View;
$view->filename = 'test.phtml';
$view->dir = './';
$view->variables = array('test' => 'tset');
echo $view->render('test.phtml');
var_dump($view->returned);

//test.phtml
<p><?php echo $test; ?></p>

Hemen hemen Zend_View çoğaltılmış ettik - bazı alternatif dizinleri ile, dosya var ve tanımlanmış değişkenler ve yöntemler olmadığını denetler.

Belirli variabels kod çalıştırabilir ve eski php kodu ile kullanmak için bu sonucu elde etmek için include sonra *, siz de () * $ this-> outVariables = get_defined_vars ekleyebilirsiniz.

Küresel kapsamda ($ _GET) asla çıkartılmamalıdır. Bunun dışında, (potansiyel) isteğe bağlı argümanlar çok var olabilecek bir işlev çağırarak gibi kullanımları vardır.

Bu WordPress geliştiriciler için belli belirsiz tanıdık bakmak gerekir:

function widget (Array $args = NULL)
{
    extract($args);

    if($before_widget) echo $before_widget;

    // do the widget stuff

    if($after_widget) echo $after_widget;
}

widget(array(
    'before_widget' => '<div class="widget">',
    'after_widget' => '</div>'
));

Birisi sadece yerine dizi içeren her şey, belirlediğiniz değişkenleri ayıklamak için izin vererek, farklı bir iş parçacığı, here is a safer way to use extract belirtildiği gibi.

Bu değişkenler böylece değişken bir alışkanlık bu kadar zor geri izleme dışarı geliyor ne belgeleyen ikili bir amaca hizmet eder.

Risk register_globals ile aynıdır. Sadece isteği ile oynamalar yaparak, komut değişkenleri ayarlamak için saldırganın sağlar.