• 浅谈 PHP 变量可用字符


    先来说说php变量的命名规则,百度下一抓一大把:
    (1) PHP的变量名区分大小写;
    (2) 变量名必须以美元符号$开始;
    (3) 变量名开头可以以下划线开始;
    (4) 变量名不能以数字字符开头.

    其实所有编程都类似的命名规范就是:
    1. 变量第一个字符最好是 字母或_,不能以数字开头
    2. 第二个字符开始允许 数字,字母,_

    好了,差不多就是这样了,但是这不是我们要说的重点。
    今天我们说说 PHP 变量的可用字符,不仅仅是 数字,字母,_ 哦。

    前几天QQ上一朋友发我一个shell,是加密过的,通篇乱码,不过上面有注释,叫做 “神盾加密” 好霸气的样子。
    里面用了一些比较生僻的知识点,其中最明显的就是变量名,所以今天我们先从变量开始讲。

    当然网上我也没找到权威的质料强有力的说明PHP的变量名可用字符的信息,所以我只能自己测试了。(英文不好,没办法谷歌到有利的证据)
    先来看下我所用的方法,(如果你有更好的方法,希望分享下。)

    <?php
    if ($_POST) {
        $chr = chr($_POST['chr']);
        eval('$'.$chr."=1;");
        echo 'ok';
        exit;
    }
    ?>
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>test</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.js"></script>
    </head>
    <body>
        <script>
        for(var i = 0x00; i <= 0xFF; i++) { // 0x00 - 0xFF  255个字符
            $.ajaxSettings.async = false; // 同步模式, 为了按顺序返回数据
            $.post( "?", {chr: i}, (function (data) { // post i 给 php 解析
                data === 'ok' && console.log( "\x"+(i).toString(16) ); // 如果只返回 ok 说明能正常执行,否则会抛出异常
            });
        }
        </script>
    </body>
    </html>

    代码还算比较简单,PHP 部分只负责解析每一个字符当作变量名的执行结果是否会抛出溢出。
    比如 字符 a 那么会解析  eval('$a=1;');  这样的结果肯定没问题,所以不会抛出异常,返回结果就是 ok 字符。
    如果 字符 - 那么会解析  eval('$-=1;');  这明显是不对的,所以会抛出  PHP Parse error: syntax error, unexpected '-', expecting T_VARIABLE or '$'  和 ok 字符。
    而下面的 ajax 部分者正是利用返回结果是否为 'ok' 而判断是否是有效的变量名。
    看看执行后的结果是什么吧:

    "x41, x42, x43, x44, x45, x46, x47, x48, x49, x4a, x4b, x4c, x4d, x4e, x4f, x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5a, x5f, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6a, x6b, x6c, x6d, x6e, x6f, x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7a, x7f, x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8a, x8b, x8c, x8d, x8e, x8f, x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9a, x9b, x9c, x9d, x9e, x9f, xa0, xa1, xa2, xa3, xa4, xa5, xa6, xa7, xa8, xa9, xaa, xab, xac, xad, xae, xaf, xb0, xb1, xb2, xb3, xb4, xb5, xb6, xb7, xb8, xb9, xba, xbb, xbc, xbd, xbe, xbf, xc0, xc1, xc2, xc3, xc4, xc5, xc6, xc7, xc8, xc9, xca, xcb, xcc, xcd, xce, xcf, xd0, xd1, xd2, xd3, xd4, xd5, xd6, xd7, xd8, xd9, xda, xdb, xdc, xdd, xde, xdf, xe0, xe1, xe2, xe3, xe4, xe5, xe6, xe7, xe8, xe9, xea, xeb, xec, xed, xee, xef, xf0, xf1, xf2, xf3, xf4, xf5, xf6, xf7, xf8, xf9, xfa, xfb, xfc, xfd, xfe, xff"

    整理后发现是这样的16进制数据,当然看不懂没关系,看下转义后的结果:

    "A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, _, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, , ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,  , ¡, ¢, £, ¤, ¥, ¦, §, ¨, ©, ª, «, ¬, ­, ®, ¯, °, ±, ², ³, ´, µ, ¶, ·, ¸, ¹, º, », ¼, ½, ¾, ¿, À, Á, Â, Ã, Ä, Å, Æ, Ç, È, É, Ê, Ë, Ì, Í, Î, Ï, Ð, Ñ, Ò, Ó, Ô, Õ, Ö, ×, Ø, Ù, Ú, Û, Ü, Ý, Þ, ß, à, á, â, ã, ä, å, æ, ç, è, é, ê, ë, ì, í, î, ï, ð, ñ, ò, ó, ô, õ, ö, ÷, ø, ù, ú, û, ü, ý, þ, ÿ"

    除了前面的 A-Z_a-z 是我们熟悉的,后面的那些乱七八糟的东西竟然也能当作正常的变量名,简直不可思议。
    其实只是PHP拓展了变量名的字符范围,在 A-Z_a-z 之上,将变量可用字符范围拓展到了 x7f-xff。
    所以,第一个字符范围应该是 [a-zA-Z_x7f-xff]
    那么第二个字符是否也是这样能,我们继续测试下。
    将上面 php 代码里的  eval('$'.$chr."=1;");  改成  eval('$a'.$chr."=1;");  保存测试、

    "x9, xa, xd, x20, x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4a, x4b, x4c, x4d, x4e, x4f, x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5a, x5f, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6a, x6b, x6c, x6d, x6e, x6f, x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7a, x7f, x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8a, x8b, x8c, x8d, x8e, x8f, x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9a, x9b, x9c, x9d, x9e, x9f, xa0, xa1, xa2, xa3, xa4, xa5, xa6, xa7, xa8, xa9, xaa, xab, xac, xad, xae, xaf, xb0, xb1, xb2, xb3, xb4, xb5, xb6, xb7, xb8, xb9, xba, xbb, xbc, xbd, xbe, xbf, xc0, xc1, xc2, xc3, xc4, xc5, xc6, xc7, xc8, xc9, xca, xcb, xcc, xcd, xce, xcf, xd0, xd1, xd2, xd3, xd4, xd5, xd6, xd7, xd8, xd9, xda, xdb, xdc, xdd, xde, xdf, xe0, xe1, xe2, xe3, xe4, xe5, xe6, xe7, xe8, xe9, xea, xeb, xec, xed, xee, xef, xf0, xf1, xf2, xf3, xf4, xf5, xf6, xf7, xf8, xf9, xfa, xfb, xfc, xfd, xfe, xff"

    发现结果多了好多字符,其实有一部分我们是要去掉的,比如 x20 其实就是 空格,相当于  eval('$a =1;');  而已,当然是能正常执行的。
    除了空格,还有 都去掉因为这些也是PHP语法说允许的 =x9, =xa, =xd,所以我们要去掉结果中的前4个数据x9, xa, xd, x20
    最终得到的结果其实只是多了  x30, x31, x32, x33, x34, x35, x36, x37, x38, x39  熟悉 ascii 的人也许一眼就看出来了,这就是数字 0-9
    所以第一个字符范围应该是 [wx7f-xff] 对正则不熟的也许会觉得怎么不是 [0-9a-zA-Z_x7f-xff],其实 w 就是 0-9a-zA-Z_

    也许有人会说  $$a; ${$a};  这样的变量呢?
    我觉得这个已脱离了变量命名的范围了,不是么。

    好了,关于 php 变量可用字符的知识点分享完毕了,如果有哪说的不对的,请留言,我会及时改正以免误导大家。

    我的猜测: ascii 范围 0-127(x00-x7f), latin1 范围 0-255(x00-xff),也许PHP就是将范围扩充到 latin1 字符集了,当然我没看过PHP源码,只能说是个猜想而已。

    经 @holine 提醒,我去翻了官网手册,果然找到了,好吧,我还费了这么大的劲去测试、

    查看资料 http://www.php.net/manual/zh/language.variables.basics.php

  • 相关阅读:
    原始mvc1
    ssh3,hibernate和maven
    hibernate1
    mybatis和spring一起用
    python怎么生成requirements.txt文件
    selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable (Session info: chrome=74.0.3729.108) (Driver info: chromedriver=2.43.600210
    Android SDK 安装与配置
    pip超时问题解决
    爬取网页数据
    pip安装报错: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy
  • 原文地址:https://www.cnblogs.com/52cik/p/php-variable-character.html
Copyright © 2020-2023  润新知