Доступ к переменным в вышестоящей области видимости (не глобальной)

Тема в разделе "PHP", создана пользователем Mendel, 12 мар 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. Mendel

    Mendel

    Регистр.:
    27 янв 2008
    Сообщения:
    217
    Симпатии:
    64
    Есть задача - передать функции некую конструкцию, которая будет обработана функцией, после чего выполнена.
    При этом возникает задача доступа к переменным которые были в области видимости ДО вызова функций.
    т.е. я вызываю

    $var1='100.0';
    $var2=100;
    myfunc('$var==$var2');
    и в myfunc надо иметь доступ к нашим $var1 и $var2

    PS: для особо одаренных - ГЛОБАЛ не подходит поскольку функция может вызываться и из другой функции и из разных классов и т.п.
     
  2. shutty

    shutty Создатель

    Регистр.:
    8 фев 2008
    Сообщения:
    41
    Симпатии:
    1
    Архитектурный изврат. Как вариант, после обработки, функция myfunc() выплевывает строку, которую ты потом делаешь eval().
    т.е. все будет выглядеть как eval(myfunc());
     
  3. Raenor

    Raenor Ксенолог №1

    Регистр.:
    28 дек 2006
    Сообщения:
    153
    Симпатии:
    91
    PHP:
    <?php
    function vasya ($h) {
        
    $h "hz kto";
    }
    $vasya "brother of petya";
    vasya (&$vasya);
    echo 
    $vasya;
    ?>
    может это тебе поможет)
     
  4. Mendel

    Mendel

    Регистр.:
    27 янв 2008
    Сообщения:
    217
    Симпатии:
    64
    конкретная задача:
    передать методу работы с базой данных условие на какие записи распространяется действие...
    например
    PHP:
    $uid=1;
    $ulevel=10000;
    $user->del('uid<>$uid AND ulevel == $need_ulevel');
    теперь наша функция должна сформировать запрос где будет нечто вроде
    PHP:
    $where='`uid`<>'.mysql_real_escape($uid).' AND `ulevel` == '.mysql_real_escape($need_ulevel);
    такая конструкция была бы правильна в области видимости в которой вызывалась функция. Но у нас уже другая область видимости. И если мы сделаем к примеру
    PHP:
    function test()
      {
       
    $uid=1;
       
    $ulevel=10000;
       
    $user->del('uid<>$uid AND ulevel == $need_ulevel');
      }
    то глобал нам уже совсем не поможет ибо оно даст нам глобальные переменные а нам нужны переменные из видимости той функции откуда мы ее вызывали...
     
  5. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    883
    Симпатии:
    540
    Никак. Только если хранить все переменные в глобальном массиве $_SERVER['my_arr'] и через него обращатся к переменным. А в начале каждой функции приводить инициализацию. Например
    PHP:
    $eee '1var';
    $_SERVER['my_arr']['eee'] =& $eee;
    var_dump($_SERVER['my_arr']['eee']);
    $eee='var2';
    var_dump($_SERVER['my_arr']['eee']);
    function 
    a(){
        foreach(
    $_SERVER['my_arr'] as $name=>$value){
          $
    $name =& $value;    
          
    $_SERVER['my_arr']['eee'] =& $$name;    
        }
        
    $eee 'var3';
    }
    a();
    var_dump($_SERVER['my_arr']['eee']);
    HTML:
    string '1var' (length=4)
    string 'var2' (length=4)
    string 'var3' (length=4)
    
     
  6. zss

    zss Постоялец

    Регистр.:
    22 июн 2007
    Сообщения:
    55
    Симпатии:
    6
    На мой взгляд можно не мудрить, а просто передать нужные параметры
    Код:
    function test($uidPar,$need_ulevelPar)
      {
       $uid=1;
       $ulevel=10000;
       $user->del('uid<>$uidPar AND ulevel == $need_ulevelPar');
      }  
    
    Тогда $uidPar,$need_ulevelPar будут формальными параметрами,
    которые при вызове заменятся фактическими $uid и $ulevel из вызывающей функции.
    А в коде
    $uid=1;
    $ulevel=10000;
    $uid и $ulevel - собственные локальные переменные.
     
  7. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    883
    Симпатии:
    540
    всё таки ТЗ немного другое- надо сделать доступным не просто какое либо значение переменной, а саму переменную. Как я предполагаю это для интеграции различных скриптов. Часто без заплаток через левую Ж не обойтись. Другое применение в пхп придумать трудно (т.к. в других языках это встречается)
     
  8. Abliganto

    Abliganto Постоялец

    Регистр.:
    30 ноя 2009
    Сообщения:
    111
    Симпатии:
    46
    Видимо ТС хочет работать с переменными как в JavaScript, там такое прокатит на ура :)

    На самом деле задача в том виде, в каком она описана в т.н. ТЗ глупа. Если вызываемая цепочка ф-ций и методов классов знает о какой-то "волшебной" переменной, значит эта "волшебная" переменная должна быть передана как аргумент либо объявлена глобальной. Либо во всей цепочке вызовов использовать global и перечислять там каждый раз все переменные (помнится, такие мега-структуры были в PHP-nuke лет 8 назад :)).
     
  9. Mendel

    Mendel

    Регистр.:
    27 янв 2008
    Сообщения:
    217
    Симпатии:
    64
    На мой взгляд стоит быть внимательным, и увидеть в моем коде mysql_real_escape :)
    Искренне надеюсь, что вы просто невнимательны и не знаете некоторых элементарных вещей, например таких как sql injection а не тупо набиваете посты.
    Когда у меня возникает ситуация, когда нужно набить посты, то я сначала читаю то, что написал ТС, а потом уже пишу. Я ж ведь не чукча :)
    Специально для ВАС я писал о том, что глобал не покатит. Причем ДВАЖДЫ писал.
    Советую не путать понятия "задача не реализуема стандартными методами" и "задача глупа".
    Другое применение было озвучено в топике :)
    Задача в том, чтобы сделать простой вызов модуля базы данных и при этом не попасть на sql injection
    Задача осложняется тем, что это фреймворк. А значит я не могу контролировать код прикладного программиста - только свой собственный код :)
    В принципе я не вижу откуда могут взяться не санированные данные, но ситуации бывают разные. С инъекциями через куки я давно сталкивался, но вот с инъекцией через реферер столкнулся только недавно. (для статистики... туда же можно было и через юзерагент влезть). Поэтому рассчитывать на эскейпинг данных не стоит.
    Ну и еще - название столбцов стоит брать в обратные кавычки, а переменные не только для защиты надо эскейпить и в кавычки брать - кавычки и прочие символы могут быть не только в злонамеренных данных, но и в вполне обычных...
     
  10. Abliganto

    Abliganto Постоялец

    Регистр.:
    30 ноя 2009
    Сообщения:
    111
    Симпатии:
    46
    Я конечно извиняюсь, т.к. почему-то не заметил вашего поста с конкретным примером. По этому весь мой комментарий строился на базе первого поста.
    Для этой задачи обычно используют placeholder'ы.
    PHP:
    $uid=1;
    $ulevel=10000;
    $user->del('uid<>? AND ulevel == ?'$uid$ulevel);
    // Класс User
    public function del$query )
    {
      
    $args func_get_args();
      
    //...
    }
    Моя цель не банальный набор постов, заметьте, я никогда не пишу воду, всегда даю дельный совет. Вы просите помощи у студии - если у задачи нет единственного правильного решения будут поступать различные ответы. Вы ведь сами прекрасно понимаете, что невозможно получить доступ к переменным.
     
    Mendel нравится это.
Статус темы:
Закрыта.