Идея глобальных переменных просто замечательная, однако многие не рекомендуют их использовать, т.к. это нарушает архитектуру программы и может привести к непредвиденным результатам, так это или не так, однако, наряду с недостатками есть у них и достоинства - к ним всегда можно обратиться из любого места в программе, особенно не заморачиваясь.
В PHP есть также т.н. суперглобальные переменные - $_POST, $_GET.
Уж не знаю почему разработчики их допустили, в ведь у суперголобальных переменных недостатки глобальных переменных становятся супернедостатками. Ну да не об этом речь.
Захотелось мне сделать свои суперглобальные переменные куда я хочу поместить значения из $_POST и $_GET, но без magic_quotes.
Зачем это нужно? Да просто мне не очень хотелось портить оригинальные значения переменных из соображений универсальности кода.
Как быть? Суперглобальные переменные нельзя создать - они накрепко зашиты в PHP и новые суперглобальные переменные сделать невозможно, но я нашел один выход из данной ситуации.
PHP5 позволяет создавать статические переменные класса, т.к. область видимости класса - весь код, то и полученная переменная ведет себя как суперглобальная. Красота.
class Site{
static $POST;
static $GET;
static $COOKIE;
static function stripslashes($val){
$type = gettype($val);
if ($type=='string'){
return stripslashes($val);
}
elseif($type=='array'){
$var1 = array();
foreach($val as $key=>$value){
$var1[$key] = Site::stripslashes($val[$key]);
}
return $var1;
}
else {
return $val;
}
}
static function initSite(){
if (ini_get('magic_quotes_gpc')){
Site::$GET = Site::stripslashes($_GET);
Site::$POST = Site::stripslashes($_POST);
Site::$COOKIE = Site::stripslashes($_COOKIE);
}
else {
Site::$GET = $_GET;
Site::$POST = $_POST;
Site::$COOKIE = $_COOKIE;
}
}
}
Site::initSite();
При этом полученные переменные Site::$POST и Site::$GET ведут себя также как и аналогичные классические аналоги $_POST и $_GET.
Недавно на баше наткнулся на симпатичный пост
Возможно, такой код на самом деле имеет право на существование, ведь в отличие от матeматики в программировании от перемены мест слагаемых сумма может измениться, особенно, если слагаемые имеют разный тип.
Вот если написать простейший код на JavaScript
<html>
<head>
<title>Дзен-программизм</title>
</head>
<script type="text/javascript">
intQuanty = 1;
intQuanty = intQuanty + 0;
alert(intQuanty);
</script>
</html>
Результат выполнения программы будет "1" как и следовало ожидать.
Однако стоит сделать переменную intQuanty строковой, то результат будет совсем другой
<html>
<head>
<title>Дзен-программизм</title>
</head>
<script type="text/javascript">
intQuanty = "1";
intQuanty = intQuanty + 0;
alert(intQuanty);
</script>
</html>
Что и требовалось доказать! Конечно ноль лучше бы поставить в кавычки, однако для того чтобы запутать всех в конец можно и так оставить.
Думаю, если сделать аналогичные эксперименты на других языках результаты получатся даже интереснее.
Однажды показал такой фокус одинеснице - так она на меня смотрела как на прокаженного.
Сегодня встала задача сделать страничку с ютубовскими мувиками валидной в XHTML Transitional. Сама по себе задачка решена давно, можно использовать для этих целей SWFObject, но он зараза никак wmode не позволяет менять, или я просто не умею это делать. Кроме того синтаксис его использования какой-то громоздкий и некрасивый. Решил своими силами сделать аналог посимпатичнее.
Конечно за безбаговость не ручаюсь но потестировал на IE6, IE7, в Опере, FF и Sаfari.
Самое интересное что код с тегом Object нигде не понадобился. Я то думал что он нужен для эксплорера, оказывается что шестой эксплорер тег Object кушать наотрез отказался, а вот EMBED скушал за милую душу.
Вот что получтилось:
flasher.js
function flasher(){
this.attr = {'wmode':'transparent','type':'application/x-shockwave-flash'};
var i;
for(i=0;i<arguments.length;i=i+2){
this.attr[arguments[i]] = arguments[i+1];
}
}
flasher.prototype.write = function(element){
var el = document.getElementById(element);
var args = '';
for(key in this.attr){
args = args + ' ' + key+'='+this.attr[key];
}
el.innerHTML = '<embed '+args+'></embed>';
}
как это использовать:
<div style="width:425px;margin:10px auto;" id="darren_dicke"><!--Darren Dicke--></div>
<script type="text/javascript">
// <![CDATA[
var fo = new flasher("src", "http://www.youtube.com/v/g3Y_mQA0E0A", "width","425", "height","350" );
fo.write("darren_dicke");
// ]]>
</script>
к недостаткам можно отнести отсутствие автообновления плагина, займусь этим как нибудь на досуге потом.