我想允许提交小的用户定义的正则表达式进行测试.但是,从失控服务器使用到更恶习的eval()使用还有许多问题需要考虑.
据我所知,我已经处理了以下代码中我能想到的所有问题.他们没有想到的任何攻击媒介吗?(我知道一个相当天真的问题)
function testRegex($regex)
{
// null character allows a premature regex end and "/../e" injection
if (strpos($regex, 0) !== false || ! trim($regex)) {
return false;
}
$backtrack_limit = ini_set('pcre.backtrack_limit', 200);
$recursion_limit = ini_set('pcre.recursion_limit', 20);
$valid = @preg_match("~$regex~u", null) !== false;
ini_set('pcre.backtrack_limit', $backtrack_limit);
ini_set('pcre.recursion_limit', $recursion_limit);
return $valid;
}
$regexes = array(
"InvalidRegular)Expression",
'',
'\w+',
'\/\w+/',
'foo[bar]*',
'\/\x00known/e' . chr(0x00) . chr(0),
'known~e' . chr(0),
'known~e' . chr(0x00),
'[a-z]+',
'\p{Lu}+',
);
foreach($regexes as $regex) {
var_dump($regex, testRegex($regex));
} …Run Code Online (Sandbox Code Playgroud) 我有用户提交的标签,可以是任何类型的(有效)UTF-8字符串.我想知道通过运行它们是否可以安全地将它们包含在URL中urlencode().
换句话说,urlencode()是否可以安全地用于有效的UTF-8字符串?(通过有效我的意思是id已经强制编码为UTF-8)
据我所知,我们在PHP中使用命名空间的唯一原因是修复类(+函数和常量)与其他同名类冲突的问题.
问题是大多数框架设置自动加载和文件系统层次结构以反映类的名称.并且没有人实际上需要()s或include()s文件.
那么命名空间如何帮助这个呢?要么根据它的名称加载类:
new Zend_Db_Table_Rowset_Abstract;
Run Code Online (Sandbox Code Playgroud)
或者它的命名空间
new Zend\Db\Table\Rowset\Abstract;
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,我只是能够创建一个具有此名称的类.
/var/www/public/Zend/Db/Table/Rowset/Abstract.php
Run Code Online (Sandbox Code Playgroud)
更新 我不确定我是否明白了.
即使我创建了两个相同的文件,class Zend\Db\Table\Rowset\Abstract我仍然无法一起使用它们,因为它们都声称具有相同的命名空间.我必须改变他们的命名空间名称,这是我们已经做的!
这让我相信命名空间的唯一用途是函数名称.现在我们终于可以将三个函数命名为同一个东西!
或者等一下,我忘了你不能这样做,因为每个都需要命名空间前缀!
a\myfunction();
b\myfunction();
c\myfunction();
Run Code Online (Sandbox Code Playgroud)
以ircmaxell为例:
$model = new \Application\Model\User;
$controller = new \Application\Controller\User;
Run Code Online (Sandbox Code Playgroud)
那有什么不同而不是没有?
$model = new Application_Model_User;
$controller = new Application_Controller_User;
Run Code Online (Sandbox Code Playgroud)
这也是一个整洁的声音功能 - 但它真正为我们做了什么?
use \Application\Model\User as UserModel;
use \Application\Controller\User as UserController;
$foo = new UserModel;
$bar = new UserController;
Run Code Online (Sandbox Code Playgroud)
现在您不能拥有一个名为"UserModel"的类,因为您有该术语的命名空间设置.您也仍然不能有相同的别名下名为两班.
我想好的是你可以重命名 Zend_Db_Table_Rowset_Abstract
use Zend_Db_Table_Rowset_Abstract as RowAbstract;
Run Code Online (Sandbox Code Playgroud)
导致开发人员对系统中定义和来自不存在的类"RowAbstract"的位置感到困惑.
我有一小段一些数据(小于1kb),我希望用户代理从我的网站发送到其他网站.为了让其他站点验证我是创建字符串的那个,我有两个选项.
我不想设置HMAC,因为这意味着我必须为每个站点使用自定义键,这将是一个痛苦.
在这两个选择中,似乎#2会节省带宽,这使它看起来是更好的选择.
那么如何使用PHP设置公钥/私钥加密,是否有任何缺点?
Angular.js默认情况下不提供人类可读的错误消息.
反正有没有将默认的,神秘的Angular.js异常URL更改为更易读的错误消息?实际上,我必须复制URL,删除前缀,然后粘贴到浏览器中以查看问题所在.
例如,将以下异常转换为更有用的错误消息:
Error: [ng:areq] http://errors.angularjs.org/1.3.0/ng/areq?p0=InterfaceController&p1=not%20a%20function%2C%20got%20undefined y/<@https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular....
Run Code Online (Sandbox Code Playgroud)
对于这样的事情:
"Missing required argument to InterfaceController"
Run Code Online (Sandbox Code Playgroud)
我知道我可以提供自己的异常处理程序:
.factory('$exceptionHandler', function () {
return function errorCatcherHandler(exception, cause) {
console.error(exception);
};
});
Run Code Online (Sandbox Code Playgroud)
我接近这个错吗?
如今,"准备好的语句"似乎是任何人建议向数据库发送查询的唯一方式.我甚至看到了为存储过程使用预准备语句的建议.然而,这样做的额外查询预处理语句需要 - 他们持续很短的时间 - 我相信,他们只负责线路INSERT/UPDATE查询有用.
我希望有人可以纠正我,但这似乎是整个"桌子是邪恶的"CSS事件的重复.如果用于布局,表格只是邪恶的 - 而不是表格数据.将DIV用于表格数据是违反WC3的风格.
同样明智的,纯SQL(或从AR生成的)似乎对80%的查询更有用,在大多数站点上都是单个SELECT,不再重复页面加载(我说的是脚本语言)像这里的PHP).为什么我会让我过度征税的数据库准备一个声明,它只能在删除之前运行一次?
MySQL的:
准备好的语句特定于创建它的会话.如果在不释放先前准备的语句的情况下终止会话,则服务器会自动解除分配.
因此,在脚本结束时,PHP将自动关闭连接,您将丢失准备好的语句,只是为了让您的脚本在下次加载时重新创建它.
我错过了什么或者这只是一种降低性能的方法吗?
:更新时间:
我突然意识到我正在为每个脚本假设新的连接.我认为如果使用持久连接,那么这些问题就会消失.它是否正确?
:UPDATE2:
似乎即使持久连接是解决方案 - 它们对于大多数Web来说也不是一个非常好的选择 - 特别是如果你使用事务.所以我回到原点,只有下面的基准才能继续......
:UPDATE3:
大多数人只是重复"准备语句防止SQL注入"这一短语,但并没有完全解释这个问题.为每个DB库提供的"转义"方法也可以防止SQL注入.但它不止于此:
以正常方式发送查询时,客户端(脚本)将数据转换为字符串,然后传递给数据库服务器.然后,DB服务器使用CPU电源将它们转换回正确的二进制数据类型.然后,数据库引擎解析该语句并查找语法错误.
使用预准备语句时...数据以本机二进制形式发送,这样可以节省转换CPU使用率,并使数据传输更加高效.显然,如果客户端与DB服务器不在同一位置,这也会减少带宽使用.
...变量类型是预定义的,因此MySQL会考虑这些字符,并且不需要对它们进行转义.
感谢OIS最终在这个问题上设置了我.
那里有几个ActiveRecord样式的查询构建器库.有些是独立的,有些是内置于框架中的.但是,当涉及到复杂的SQL时,它们确实遇到了WHERE和HAVING子句的问题.将其他数据库放在一边 - 我试图想出一个MySQL和PostgreSQL兼容的WHERE()方法,可以解决这些当前方法的垮台.
接下来是一长串的想法和例子,展示了迄今为止我能想到的最好的想法和例子.但是,我似乎无法解决所有用例,我觉得我的部分解决方案很草率.任何可以用解决所有这些问题的方法回答的人不仅会回答这个问题 - 而且还会负责解决几年来一直困扰着PHP实施的问题.
共同运营商
= Equal
<> Not Equal
> Greater Than
< Less Than
>= Greater Than Or Equal
<= Less Than Or Equal
BETWEEN between values on right
NOT logical NOT
AND logical AND
OR logical OR
Run Code Online (Sandbox Code Playgroud)
示例where子句
SELECT ... FROM table...
WHERE column = 5
WHERE column > 5
WHERE column IS NULL
WHERE column IN (1, 2, 3)
WHERE column NOT IN (1, 2, 3)
WHERE column …Run Code Online (Sandbox Code Playgroud) 使用标准RDMS,我可以通过使用主键和外键找到关系.如果我想要最近的评论,那么我只是按日期时间排序.如果我想要用户的所有评论,那么我将获取评论属于该用户的位置.
换句话说,我可以使用索引来过滤结果.不只是主键.
但是,对于文档和键值NoSQL,我无法弄清楚如何使用它们比文本转储更多.您唯一能做的就是通过ID获取值.
我需要一些例子,说明当你不能再使用索引或过滤器时,如何在NoSQL中建模数据.你如何排序和搜索数据?
php ×6
mysql ×2
postgresql ×2
url ×2
activerecord ×1
algorithm ×1
angularjs ×1
class ×1
cryptography ×1
database ×1
javascript ×1
libsodium ×1
namespaces ×1
nosql ×1
null ×1
pgp ×1
php-openssl ×1
regex ×1
sanitization ×1
sql ×1
storage ×1
user-input ×1
utf-8 ×1