PHP: Eşdeğer eval kullanarak içerir

5 Cevap php

Kodu aynı ise, arasında bir fark orada görünüyor:

include 'external.php';

ve

eval('?>' . file_get_contents('external.php') . '<?php');

Fark nedir? Bilen var mı?


I know the two are different because the include works fine vethe eval gives an error. When I originally asked the question, I wasn't sure whether it gave an error on all code or just on mine (vebecause the code was evaled, it was very hard to find out what the error meant). However, after having researched the answer, it turns out that whether or not you get the error does not depend on the code in the external.php, but does depend on your php settings (short_open_tag to be precise).

5 Cevap

Biraz daha araştırma sonra kendimi yanlış olduğunu öğrendim. Sorun <?php "kısa açılış etiketi" ve böylece short_open_tag (aynı etki için php.ini falan) 1 olarak ayarlandığında, yalnızca çalışacak aslında . Doğru tam etiketi ikinci p sonra bir boşluk vardır ki, <?php olduğunu.

Dahil gibi uygun eşdeğer olduğu:

eval('?>' . file_get_contents('external.php') . '<?php ');

(Aşağıdaki açıklamalarda belirtildiği gibi) Alternatif olarak, dışarı hep birlikte açılış etiketi bırakabilirsiniz:

eval('?>' . file_get_contents('external.php'));

Benim asıl çözümü de çalışan bir noktalı virgül eklemek oldu, ama bana sorarsanız çok daha az temiz görünüyor:

eval('?>' . file_get_contents('external.php') . '<?php;');

Eğer eval () kullanırsanız AFAIK php hızlandırıcıları yararlanabilirsiniz olamaz.

Eval'd kodu: Eğer APC, eval "best solution" olmayacak gibi bir opcode önbellek yüklü olduğu bir web sunucusu kullanıyorsanız eğer doğru hatırlıyorum, opcode önbellek saklamak (and another answer said the same thing, btw). değil

Kullanmak verebilecek bir çözüm, en azından kod sık sık değişti değilse, veritabanında saklanır ve kodu dahil kod karışımı olsun:

  • gerektiğinde, DB kodunu almak ve bu diskte bir dosyada saklamak
  • bu dosyayı içerir
  • kod bir dosya şimdi olduğu gibi, diskte, opcode önbellek önbelleğe mümkün olacak - performansları için daha iyi olduğu
  • ve size kod çalıştırmak zorunda, her zaman DB için bir istek yapmak gerekmez.

Ben bu çözümü kullanan yazılım (diskteki dosya DB saklanan kod önbelleği daha fazla olmak üzere) ile çalıştık ve ben çok kötü değil - çalıştı şekilde daha iyi her sayfanın DB istekleri yükler yapıyor, neyse ...

Bir sonucu olarak, bazı çok iyi şeyler:

  • you have to fetch the code from the DB to put it in the file "when necessary"
    • Bu geçici dosya her saat yeniden üreten, ya da DB giriş değiştirilmiş onu silmesini anlamına gelebilir? Eğer bu durumda tanımlamak için bir yol var mı?
  • you also have to change your code, to use the temporary file, or re-generate it if necessary
    • Eğer modifiy için birkaç yer varsa, bu bazı iş anlamına gelebilir

BTW : would I dare saying something like "eval is evil" ?

Bu dosya sarmalayıcılar varsayarak PHP üzerinde içeren bir dosyayı dahil sağlar:

function stringToTempFileName($str)
{
    if (version_compare(PHP_VERSION, '5.1.0', '>=') && strlen($str < (1024 * 512))) {
        $file = 'data://text/plain;base64,' . base64_encode($str);
    } else {
        $file = Utils::tempFileName();
        file_put_contents($file, $str);
    }
    return $file;
}

... Sonra bu 'dosyası.' Içeren Evet, bu da işlem kodu önbelleğe devre dışı, ancak bir davranış ile ilgili bulunmaktadır, bu da aynı 'eval' yapar.

Sadece eval('?>' . file_get_contents('external.php')); varyant içeren için doğru yedek.

Testleri bakınız:

<?php
$includes = array(
    'some text',
    '<?php print "some text"; ?>',
    '<?php print "some text";',
    'some text<?php',
    'some text<?php ',
    'some text<?php;',
    'some text<?php ?>',
    '<?php ?>some text',
);

$tempFile = tempnam('/tmp', 'test_');

print "\r\n" . "Include:" . "\r\n";
foreach ($includes as $include)
{
    file_put_contents($tempFile, $include);
    var_dump(include $tempFile);
}

unlink($tempFile);

print "\r\n" . "Eval 1:" . "\r\n";
foreach ($includes as $include)
    var_dump(eval('?>' . $include . '<?php '));

print "\r\n" . "Eval 2:" . "\r\n";
foreach ($includes as $include)
    var_dump(eval('?>' . $include));

print "\r\n" . "Eval 3:" . "\r\n";
foreach ($includes as $include)
    var_dump(eval('?>' . $include . '<?php;'));

Çıktı:

Include:
some textint(1)
some textint(1)
some textint(1)
some text<?phpint(1)
some textint(1)
some text<?php;int(1)
some textint(1)
some textint(1)

Eval 1:
some textNULL
some textNULL
bool(false)
some text<?phpNULL
bool(false)
some text<?php;NULL
some textNULL
some textNULL

Eval 2:
some textNULL
some textNULL
some textNULL
some text<?phpNULL
some textNULL
some text<?php;NULL
some textNULL
some textNULL

Eval 3:
some text<?php;NULL
some text<?php;NULL
bool(false)
some text<?php<?php;NULL
bool(false)
some text<?php;<?php;NULL
some text<?php;NULL
some text<?php;NULL