每个人都遇到语法错误.即使是有经验的程序员也会犯错误.对于新手来说,这只是学习过程的一部分.但是,通常很容易解释错误消息,例如:
PHP Parse错误:语法错误,第20行的index.php中出现意外的'{'
意想不到的符号并不总是真正的罪魁祸首.但是行号给出了从哪里开始寻找的粗略想法.
始终查看代码上下文.语法错误往往隐藏在提及或在前面的代码行.将您的代码与手册中的语法示例进行比较.
虽然不是每个案例都匹配另一个案例 然而,有一些常规步骤可以解决语法错误.这篇文章总结了常见的陷阱:
意外的T_FUNCTION ......
意外T_IF
意外T_FOREACH
意外T_FOR
意外T_WHILE
意外T_DO
意外T_PRINT
意外T_ECHO
意外的T_INLINE_HTML ......
意外的T_PAAMAYIM_NEKUDOTAYIM ......
意外的T_OBJECT_OPERATOR ......
意外的T_DOUBLE_ARROW ......
意想不到的T_SL ......
意外的T_BOOLEAN_OR ...
意外的T_BOOLEAN_AND ......
意外的T_NS_SEPARATOR ......
您在PHP Web应用程序中实现了哪些功能(如何),因为您认为它在某种程度上" 更专业 "?或者你有个人的挑剔和代码爱好,特别是可能有用的小东西?哪些不受欢迎的代码或次要功能您花费了大量时间才能做到正确?
.
Q&A插图的编码爱好者示例:
配置数据不在数据库中:应用程序数据!=配置数据,这也是必要性和效率的问题.
URL修复:通过附加尾部斜杠来规范化所有Web地址,即使技术上不需要也是如此.
人类可读的cookie:对于数据隐私,我尝试避免不透明的会话/数据库句柄(对于用户选项,而不是授权使用).
内容协商:对RSS和Atom格式之间的简单变化有意义.但我发现很少使用它.
UI中没有数据库ID:避免将数据库内部代理键泄露到URL中.使用ORMs,db-internal密钥甚至不必泄漏到业务逻辑中.
.
第一个特征性研究奖励回合:很难确定其中一个好主意.说实话,我只能把它缩小到最喜欢的五个并将决定权交给rand().这个话题非常有趣,足以保证第二轮赏金.休息一下.也许其他人接管来改进范围.
是否有一种简单的方法来为HTMLPurifier添加HTML5规则集?
可以将HP 配置为识别新标签:
// setup configurable HP instance
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.DefinitionID', 'html5 draft');
$config->set('HTML.DefinitionRev', 1);
$config->set('Cache.DefinitionImpl', null); // no caching
$def = $config->getHTMLDefinition(true);
// add a new tag
$form = $def->addElement(
'article', // name
'Block', // content set
'Flow', // allowed children
'Common', // attribute collection
array( // attributes
)
);
// add a new attribute
$def->addAttribute('a', 'contextmenu', "ID");
Run Code Online (Sandbox Code Playgroud)
然而,这显然有点工作.由于必须注册许多新的HTML5标签和属性.即使使用现有的HTML 4标记,新的全局属性也应该是可组合的.(从文档中判断如何增加核心规则很难判断).那么,是否有更有用的配置格式/数组结构将新的和更新的标记+属性+上下文配置(内联/块/空/流/ ...)提供给HTMLPurifier?
# mostly confused about how to extend existing tags:
$def->addAttribute('input', 'type', "...|...|...");
# or …Run Code Online (Sandbox Code Playgroud) 我正在尝试自动从PHP类集合中删除命名空间,以使它们与PHP 5.2兼容.(共享主机提供商并不喜欢流氓PHP 5.3安装.不知道为什么.此外,有问题的代码不使用任何5.3功能添加,只是语法.自动转换似乎比手动或重新实现代码库更容易.)
为了重写*.php脚本,我基本上是在一个tokenizer列表上运行.标识符搜索+合并已经完成.但是我现在有点困惑如何完成实际的重写.
function rewrite($name, $namespace, $use) {
global $identifiers2; // list of known/existing classes
/*
bounty on missing code here
*/
return strtr($name, "\\", "_"); // goal: backslash to underscore
}
Run Code Online (Sandbox Code Playgroud)
将在每个找到的标识符(无论是类,函数还是常量)上调用该函数.它将接收一些上下文信息,以将本地标识符转换为绝对/全局$ name:
$name =
rewrite(
"classfuncconst", # <-- foreach ($names as $name)
"current\name\space",
array(
'namespc' => 'use\this\namespc',
'alias' => 'from\name\too',
...
)
);
Run Code Online (Sandbox Code Playgroud)
在这个阶段,我已经准备了$identifiers2一份清单.它包含所有已知类,函数和常量名称的列表(为简单起见,此处合并).
$identifiers2 = array( // Alternative suggestions welcome.
"name\space\Class" => "Class", // - list structure usable for task?
"other\ns\func1" => …Run Code Online (Sandbox Code Playgroud) 是否有一个既定的方法嵌入的gettext locale/xy/LC_MESSAGES/*在PYZ捆绑?特别是让Gtks自动小部件翻译从 ZIP存档中获取它们.
对于其他嵌入式资源pkgutil.get_deta或inspect/ get_source工作得足够好.但系统和 Python gettext API依赖于bindtextdomain提供一个简单的旧localedir; 没有资源或字符串等
所以我无法设计一个可行的甚至是远程实用的解决方法:
虚拟gvfs/ gio路径
现在使用archive://file%3A%2F%2Fmypkg.pyz%2Fmessages%2FIRI可以直接从zip读取其他文件.但是glibs g_dgettext仍然只是系统库的一个薄包装器.因此,任何此类URL都不能用作localedir.
部分提取拉链
这就是我认为PyInstaller的工作方式.但是将.pyz应用程序捆绑在一起当然有点荒谬,只是在每次调用时都预先提取.
Userland gettext .mo/ .poextraction
现在手动读取消息目录或者只是使用普通的dicts来代替它.但仅适用于应用程序中的字符串.再也没办法让Gtk/GtkBuilder暗中接他们了.
因此,我不得不手动遍历整个小部件树,标签,文本,内部小部件,markup_text等.可能,但是meh.
FUSE安装
这将是超薄的.但是当然,拉链内容可以被访问gvfs-mount等等.就好像是某种记忆力.而且我怀疑它会保持可靠性,例如两个应用程序实例正在运行,或者之前的不正确终止.(就像dunno一样,由于系统库,比如gettext,在一个脆弱的拉链保险丝点上磕磕绊绊......)
用于翻译的Gtk信号/事件(?)
我发现蹲下了,所以我有点确定在Gtk/PyGtk/GI中没有替代机制来进行小部件翻译.Gtk/Builder期望并与 gettext相关联.
是否有更可靠的方法?
如何根据客户端浏览器的语言重写nginx中的位置?
例如:我的浏览器接受语言是' uk,ru,en '.当我请求位置时,mysite.org nginx必须转发到mysite.org/uk
PHP无论如何都允许变量,函数,类和常量的Unicode标识符.它当然是为本地化应用程序.除了英语是有争议的,在任何事情上编写API都是一个好主意,但是一些开发设置可能要求它是无可争议的.
$Schüssel = new Müsli(T_FRÜCHTE);
Run Code Online (Sandbox Code Playgroud)
但PHP不仅仅是\p{L}标识符.您可以使用几乎任何Unicode字符,但ASCII范围除外(例如:,特殊情况或\已经用作支持命名空间的内部黑客).
无论如何,您可以这样做,我甚至认为这对于有趣的项目是可行的:
throw new ?_?("told you about the disk space before");
Run Code Online (Sandbox Code Playgroud)
但除了本地化,娱乐和装饰效果之外,使用Unicode标识符是可取的吗?
例如,我正在考虑将参数嵌入到魔术方法名称中.在我的情况下,我只需要注入数字参数,所以只用下划线就可以了:
$what->substr_0_50->ascii("text");
// (Let's skip the evilness discussion this time. Not quite sure
// yet if I really want it, but the conciseness might make sense.)
Run Code Online (Sandbox Code Playgroud)
但如果我想嵌入其他文本参数,我需要另一个unicode字符.现在更难打字,但如果有一个有助于提高可读性并传达意义......?
->substr?0?50-> // doesn't look good
Run Code Online (Sandbox Code Playgroud)
因此,在这种情况下的问题:哪个符号作为虚拟函数名称中的混合参数的分隔符是有意义的. - 更广泛的元主题:你知道哪些使用Unicode标识符,或者你会考虑好吗?
有哪些更好的方法可以避免isset()应用程序逻辑中的大量内容,并且在需要时保留查看调试消息(E_NOTICE)的能力?
首先推定:E_NOTICE不是错误,它是用词不当,实际上应该是E_DEBUG.然而,虽然这对于未设置的变量(PHP仍然是脚本语言)是正确的,但是一些文件系统函数等也会抛出它们.因此,需要开发 E_NOTICEs.
然而,并非所有调试通知都是有用的,这就是为什么在整个应用程序逻辑中引入isset()和@ 是一个常见的(不幸的)PHP习惯.isset/empty肯定有很多有效的用例,但总的来说它似乎是语法盐,实际上可能阻碍调试.
这就是我目前使用error_reporting书签和哑开/关开关的原因:
// javascript:(function(){document.cookie=(document.cookie.match(/error_reporting=1/)?'error_reporting=0':'error_reporting=1')})()
if (($_SERVER["REMOTE_ADDR"] == "127.0.0.1")
and $_COOKIE["error_reporting"])
{
error_reporting(E_ALL|E_STRICT);
}
else {/* less */}
Run Code Online (Sandbox Code Playgroud)
然而,这仍然让我有一个问题,即一旦启用就有太多通知来搜索.作为解决方法,我可以使用@ error suppress运算符.与isset()不同,它不会完全终止调试选项,因为自定义错误处理程序仍然可以接收抑制的E_NOTICE.因此,将预期的调试通知与潜在问题分开可能会有所帮助.
然而,这同样令人不满意.因此问题.有没有人使用或知道更复杂的PHP错误处理程序.我在想象:
当然,某些框架必须已经有这样的用户错误处理程序.
哦,我有人请帮助改写这个.冗长的解释失败了.
赏金更新:马克已经得到了很好的答案.改编:=进入:,下面.但是,除了DBIx之外,我还在寻找类似的方案.我只对与任何东西兼容感兴趣.
我需要建议我在参数化SQL语句中为"扩展"占位符选择的语法.因为构建一些构造(IN子句)让我烦恼,我决定使用一些自动扩展为普通的语法快捷方式?占位符.
我喜欢他们.但我想打包它以便分发,并且问我自己是否容易理解.
基本上我的新占位符是??和:?(枚举参数)和:&和:,(:|以及::(对于命名占位符)具有以下用例:
-> db(" SELECT * FROM all WHERE id IN (??) ", [$a, $b, $c, $d, $e])
Run Code Online (Sandbox Code Playgroud)
该??扩展到?,?,?,?,?,...依赖于的$ args数到我的分贝()FUNC.这个很清楚,它的语法已经标准化了.Perls DBIx :: Simple也使用它.所以我很确定这是一个可以接受的想法.
-> db(" SELECT :? FROM any WHERE id>0 ", ["title", "frog", "id"]);
// Note: not actually parameterized attr, needs cleanup regex
Run Code Online (Sandbox Code Playgroud)
承认它.我只喜欢笑脸.基本上这个:?占位符将关联$ args扩展为普通列名.它实际上抛弃了任何$ args值.它实际上对于INSERT和??有时是有用的,有时对于IN子句也是有用的.但是在这里我已经想知道这种新语法是否合理,或者只是用词不当,因为它混合了:和?字符.但不知何故,它似乎很好地匹配语法方案.
-> db(" UPDATE some SET :, WHERE :& AND (:|) …Run Code Online (Sandbox Code Playgroud) 我正在寻找一个包含脚本/类的插件multipart/form-data,它可以解析并填充$_POST(+ raw)并$_FILES从中填充.通常PHP会自己做.但是因为自动处理对我来说是不够的并且使得php://input不可能[1]我可能会使用这样的东西来防止:
RewriteRule .* - [E=CONTENT_TYPE:noparsing/for-you-php]
不行.实际解决方案需要mod_headers和RequestHeader set......
提取过程可能不那么复杂.但我宁愿使用经过充分测试的解决方案.最重要的是,我更喜欢fgets用于拆分的实现,并且$_FILES密切有效地模仿处理.找到二进制有效负载的结束对我来说似乎相当棘手,特别是当您必须剥离\r\n但可能遇到仅发送\n(不允许但可能)的客户端时.
我确定这样的事情存在.但是我很难用谷歌搜索它.有谁知道实施?(PEAR :: mimeDecode可以被黑客攻击以获得表单数据的工作方式,但是内存耗尽.)
用例简而言之:需要保留原始字段名称(包括空格和特殊字符),以便进行日志记录,但始终无法避免文件上载.
出于装饰目的,这就是POST请求的外观:
POST / HTTP/1.1
Host: localhost:8000
Content-Length: 17717
Content-Type: multipart/form-data; boundary=----------3wCuBwquE9P7A4OEylndVx
Run Code Online (Sandbox Code Playgroud)
在一个\r\n\r\n序列之后,multipart/payload遵循如下:
------------3wCuBwquE9P7A4OEylndVx
Content-Disposition: form-data; name="_charset_"
windows-1252
------------3wCuBwquE9P7A4OEylndVx
Content-Disposition: form-data; name=" text field \\ 1 \";inject=1"
text1 te twj sakfkl
------------3wCuBwquE9P7A4OEylndVx
Content-Disposition: form-data; name="file"; filename="dial.png"
Content-Type: image/png
IPNG Z @@@MIHDR@@B`@@B;HF@@@-'.e@@@AsRGB@.N\i@@@FbKGD@?@?@? ='S@@@
@@@GtIMEGYAAU,#}BRU@@@YtEXtComment@Created with GIMPWANW@@ @IDATxZl]w|
Run Code Online (Sandbox Code Playgroud) php ×8
browser ×1
debugging ×1
gettext ×1
glib ×1
html5 ×1
htmlpurifier ×1
identifier ×1
namespaces ×1
nginx ×1
parsing ×1
pygtk ×1
python ×1
pyz ×1
rewrite ×1
sql ×1
syntax-error ×1
tokenize ×1
unicode ×1