Дело было вечером, echo «было нечего»

    Добрый день хабр. В статье я расскажу, как используя синтаксис php, можно написать функцию для вывода переданной ей строковой переменной, не использующую в своем теле символы «a-zA-Z0-9<>?»

    Вообще на хабре уже проскальзывали ссылки на статьи об использовании undefined variable, так что ничего нового я скорее всего не открою.


    В php, как и в любом языке с динамической типизацией, есть моменты скрытые от конечного разработчика, на них мы и сыграем.

    Начнем с конца. Мы всегда можем обратится к любому callable- была бы строка для вызова. Функции из SPL не исключение, хоть это и крайне редко применяется.
    $v="print_r";
    $v([1,2,3,4]);
    

    Array
    (
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    )

    Но обратится таким способом ни к echo ни к print мы не можем, ибо они являются конструкциями языка, а не функциями. Можно было бы использовать printf например, но мне такой подход не понравился. Поэтому мы будем использовать для вывода функцию assert.
    assert("print someShit");
    

    Кстати заменить print на echo в выражении выше не выйдет, они оба не функции, но print хотя бы старается таковой казаться.

    Строку для вывода нам передадут при вызове. Осталось самая малость. Получить строки «assert» и «print» используя доступный нам набор символов.

    Для этого мы используем ряд особенностей языка.
    1) В php мы можем обратится к undefined variable через _ (underscore). Нетрудно добится сужения типа и получить 0
    var_dump(+_);
    

    int(0)
    2) При приведении массива к строке, он будет преобразован в строку со значением Array
    //инициализируем пустой массив
    $_[]++;
    // В данном случае _ приводится к строке "_"
    $_[]=$_._;
    var_dump($_);
    

    array(2) {
    [0]=>
    int(1)
    [1]=>
    string(6) "Array_"
    }

    3) Как и в большинстве других языков, строка фактически является массивом символов. Символы можно инкрементировать.

    Скомбинировав все вышеперечисленное получаем такой код.

    <?
    error_reporting(E_ALL^E_NOTICE);
    crazyOutput("было нечего");
    
    function crazyOutput($__________){
    $_[]++;
    $_[]=$_._;
    $_=$_[$_[+_]];
    $___=$__=$_[++$__[]];
    $____=$_=$_[+_];
    $_++;$_++;$_++;
    $_=$____.++$___.$___.++$_.$__.++$___;
    $__=+_;$__=++$__+(++$__);
    $____=$_[$__];
    $____++;$____++;$____++;
    $______=$____;
    $____++;$____++;$____++;$____++;$____++;$____++;$____++;$____++;
    $___=$____;
    $____++;$____++;
    $______++;
    $___.=$____.$______;
    $______++;$______++;$______++;$______++;$______++;
    $___.=$______;
    $__=+_;$__++;
    $______=$___[$__];
    $______++;$______++;
    $___.=$______;
    $_($___." '".$__________."'");
    }
    ?>
    


    /usr/bin/php /var/www/garbage/brainfuck.php
    было нечего
    Process finished with exit code 0


    Практической пользы 0 в принципе… но что-то в этом есть =)

    P.S Рекомендуется к прочтению
    http://insert-script.blogspot.co.uk/2012/12/php-non-alpha-numeric-76-chars.html

    http://www.thespanner.co.uk/2012/08/21/php-nonalpha-tutorial/
    Поделиться публикацией

    Похожие публикации

    Комментарии 21
      +32
      «Жениться тебе надо, барин» (с)

      А в общем затейно, мне понравилось.
        +7
        Я женат =D
        +4
        Было бы здорово, если бы без нотисов ;-)
          +8
          Мои пять копеек

          <?
          error_reporting(E_ALL^E_NOTICE);
          crazyOutput("hello world");
          
          function crazyOutput($ы) {
              $ю = ~ЏЌ–‘‹™;
              $ю(~ЪЊ, $ы);
          }
          ?>
          


          Раскурите? :)

          Кодировка — cp1251
            +3
            ~ЏЌ–‘‹™ = ~<8f><8d><96><91><8b><99>
            ~0x8f = 'p'
            ~0x8d = 'r'
            ~0x96 = 'i'
            ~0x91 = 'n'
            ~0x8b = 't'
            ~0x99 = 'f'

            ~ЪЊ = "%s"
            +4
            /me ощутил отчётливый запах Brainfuck…
            UPD: упс, не заметил…
              +1
              Вы сами это придумали? Очень похоже на www.thespanner.co.uk/2012/12/13/tweetable-php-non-alpha/
                +1
                К сожалению я не так крут — первоначально прочитал эту статью. Оттуда уже перешел на указанный вами материал. собственно формирование assErt взял оттуда. Меня смущало присутствие символов в конечном коде =)
                  0
                  Но и Вы без кавычек не обошлись )
                    +1
                    можно без кавычек запросто — call_user_func_array и printf, например. Только «брейнфака» с постинкрементами будет ОЧЕНЬ много :)
                +8
                программа из одной строчки ни Perl
                помогите, пожалуйста исправить такую программу:

                cat «test… test… test...» | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see'

                — не печатает

                anonymous (25.09.2003 8:46:28)

                www.linux.org.ru/forum/development/392747
                10 лет прошло почти
                  +1
                  Ниже в треде: «потому что ты лох, потому и не печатает :) надо перед рекурсивным входом и удалением всех директорий один слеш убрать :) ЛОХ :)»

                  И как я понял по треду, он прав!
                    0
                    UPD: не понял сразу — бред смолол
                  0
                  В php мы можем обратится к undefined variable через _ (underscore).

                  А почему именно underscore? Поясните пожалуйста или дайте ссылку на соответствующий раздел в документации
                    +1
                    Такое же имя переменной, как любое другое. Ничего особенного в _ нет, кроме экзотического вида. Любая переменная не определена, пока её не определят, и _ точно так же.
                    –1
                    Практической пользы 0, стиль написания на высоте…
                      +3
                      Тогда Вам не стоит заходить в записи из блога «Ненормальное программирование», там практичность не всегда преследуется авторами.
                      +2
                      Новогодние праздники затянулись…
                          0
                          А если набирать имена переменных через зажатый Alt + 0160, то получим «невидимый» символ. Он отображается как обычный пробел, но является разрешенным для именования переменных. Выходит можем писать такой вот головокружительный код:

                          $  = 1;
                          $  = 2;
                          var_dump($  + $  );
                          
                            0
                            в юникоде разных пробелов штук 10 наберется ;)

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое