Drupal的缓存技术应用-让你的网站飞起来
所以,你不能说要彻底解决性能问题,但你可以根据实际情况,采用一些常用的解决方案来让网站的性能得到显著提升。我们常说的80/20理论你肯定知道,那么用20%的努力换取80%的性能提升,何乐而不为呢。
Drupal作为Web开源系统的一种,被称之为CMF(内容管理框架),拥有非常优秀的架构和扩展性,以及海量的第三方模块,现在已经被越来越多的人所熟知和采用。采用Drupal这样主流Web系统的一个好处就是有好多全世界优秀的专家投入到其中,给出各种各样的性能优化方案。我们大多数人作为使用者只要知道如何选择适合自己的优化方案,就能显著提升自己网站的性能。
前面说的都是性能优化,其实本文的重点是缓存技术,在我看来,对Drupal来说,缓存和性能优化基本就是同义词,大多数Drupal的优化技术都是使用各种各样的缓存。缓存有的是静态页面缓存,有的是动态缓存,有的是CSS,Javascript和图片的缓存。有的放在内存里,有的放数据库里,有的放磁盘上,还有的还需要配合一些服务器软件来提供。林林总总,对新手来说很可能就挑花眼了,所以本文想要在缓存这个话题上,给新手一些指引,本人学识有限,不可能面面俱到,希望读者可以批评指正。
核心缓存
作为最基本的优化手段,Drupal对缓存提供了一些基本的支持,比如外部的区块缓存,匿名用户页面缓存,内部还有比如菜单系统缓存,主题钩子注册表缓存等等。
可以说,作为一个不大的Drupal站点,使用核心内置的常规手段,性能就不会太差。多说一句,一般开发阶段是不开启缓存的,但一旦上线,区块缓存和匿名用户静态页面是必须要开的,CSS和JS也一定是要开启合并压缩的。这样一来,对于匿名用户,应该说速度就会比之前快不少。
Boost
Drupal 默认提供的匿名用户缓存是存在数据库里的,这意味着即使是缓存了的网页也要占用数据库连接和内网流量。而如果换成 Boost 模块,你的缓存都直接走静态文件,这不仅仅是不走数据库了,甚至都不经过Drupal了,所以作为页面缓存来讲 Boost 的效果极为出色。
Varnish HTTP Accelerator Integration
这里把 Varnish 模块列出来只是要告诉大家,如果你的服务器仍然有很大的内存,如果在前面使用 Varnish 服务器软件,你可以将静态网页缓存到 Varnish 开辟的内存中,可想而知速度就更快了。而且Varnish还可以帮助你缓存CSS,Javascript等静态文件。
Memcache API and Integration, Memcache Storage,Redis
匿名用户的访问已经那么快了,那如果你的网站有很多活跃的登录用户怎么办呢,之前说的大部分缓存都将失效,这可如何是好呢,对于登录用户来说,最有效的就是使用 Memcache 让许多系统的内部缓存可以从内存中读取,从而得到更好的性能,并且 Memcache 本身还是可以分布式部署的,有很好的延展性。而最后一个 Redis 同样优秀,这里不会比较它们之间的优劣,只是建议你可以先从 Memcache 开始。
Memcache API and Integration和 Memcache Storage,你只需要一个,并且较为推荐后者。
APC - Alternative PHP Cache
另一个能让登录用户感觉到快起来的技术就是 Alternative PHP Cache,也就是APC,他的作用就是让PHP文件不必每次都从磁盘加载,而是可以缓存到内存,并且是缓存的编译中间代码,所以对PHP语言的复杂系统来说优化效果很明显。这可以说是所有PHP网站必装的一个组件,当然他还有其他竞争者,比如eAccelerator, XCache以及最新的Zend Opcache等组件。不过再Zend Opcache组件没出现之前,APC在Linux系统上的表现略强于其他,而新出的Zend Opcache据说可以比APC还强上一些(10%以下),但同样,这里不做比较,只是建议你可以从 APC 开始。这里有一篇文章 (link is external)可以作为你的延伸读物。
另外,如果我们紧紧是使用APC的代码文件Opcode缓存特性,是不需要APC这个模块的,这个模块提供的是存一些额外的数据缓存到APC,这样我们就能够做到一部分不经常改变的cache表放到APC,经常改变的cache表放到Memcache,另外一些大的缓存表则需要放到数据库中。
Entity cache
接下来要做什么呢,因为本文是基于 Drupal 7 的,Drupal 7 引入了 Entity 的概念之后,Drupal中就有了各种类型的 Entity,所以这个模块提供的缓存支持,会让你的登录用户感觉到快了一点点,并且无需配置,且对几乎所有的Drupal站点都生效。
另外,像这种和Drupal内核机制以及常用第三方模块相关的模块在官网还是有不少的。拿Views举例,比如Views Row Cache模块和Views content cache都为Views提供了不同逻辑的缓存机制。我们可以根据实际情况取舍这种类型的模块,毕竟模块装多了也慢。
Authenticated User Page Caching (Authcache)
然后,我们就要说说更理想的登录用户缓存问题了,如果页面是动态生成的,我们再怎么做缓存,性能上也比不过直接缓存成静态页面,那么有办法么? Authcache 模块可以在一定程度上帮到你,但要注意的是,登录用户缓存的情况非常复杂,我们在采用 Authcache 模块之前要想好适不适合自己。
举个例子,如果你做一个SNS网站,你觉得登录用户的页面不够快,如果你开启了 Authcache 模块。你就要想那些页面对用户来说是完全一样的,这样一定可以缓存,哪些页面大部分一样,只有一小部分是根据用户的不同而不同,这种对于Authcache的处理来说就要复杂一些。那么如果是像新鲜事这样的页面,你也要缓存,这对每个用户来说都是不一样的,那就意味着你要缓存页面的数量级是用户ID乘以URL数再乘以角色数,想想这样产生的缓存会占用多大的空间,真的可行吗?。
关于 Authcache 模块说了这么多,就是要提醒大家,选择 Authcache 要非常慎重,不是它不好,而是有可能不适合你。
CDN
页面的打开速度和很多因素有关,其中一个很重要的因素就是CSS和Javascript文件的下载速度。而用户与服务器之间线路的物理距离又会对此产生很大的影响,所以我们需要CDN(内容分发网络)技术的帮助,让用户可以就近访问网站资源文件的缓存版本。CDN不仅让你的网站打开速度变快,由于其还为你的网站分担了流量和连接数,所以你的网站可以支持更大的并发访问了。
CDN模块可以帮你配置,让你的CDN生效,注意一般对CSS和图片使用CDN完全没有问题,但Javascript则要注意,如果所有的Javascript代码都用CDN,可能会产生安全隐患以及用户体验等问题。
Cache Warmer
最后,再说一说缓存重建的问题,既然是缓存,那么最开始的时候是没有的,是随着用户的访问,一点点的生成的,所以用户首次访问的时候,就会觉得网站仍然很慢,假设你的网站页面非常的多,那么就会有很多用户觉得你的网站慢,甚至不再访问第二个页面就流失掉了,所以在每次清缓存之后(实际上Drupal清缓存的频率是很高的,尤其是长期迭代开发和运营的Drupal站点)我们需要为重要入口页面重建缓存,以提高访客的停留时间,降低跳出率。
Cache Warmer就是这样的技术,和爬虫的思路相比,其更有目的性,比如重要的入口页面,网站新增内容,网站热门内容等等。不过使用这一技术要注意量力而行,别在重建缓存的时候自己把自己的网站弄瘫痪了。
小结
Drupal缓存相关的模块相当多,我们可以根据项目的实际情况调研和使用。本文按照由浅入深顺序介绍了Drupal网站的各种常用缓存技术,可以让大家对Drupal的缓存技术有一个大致完整的认知,从而起到对性能优化的认知。
自动登录的原理很简单就是用户初次登录时把用户名与密码保存在cookies中,这样下次登录时加以判断cookies值中的用户名与密码是不是与数据库一样,如果是的就自动登录并设置session 即可,具体如下。
做网站的时候经常会碰到要实现记住密码,下次自动登录,一周内免登陆,一个月内免登陆这种需求。这种功能一般都是通过cookie来实现的。本篇文章将简单说一下如何使用php实现该需求的。当然实现该需求的方法有N多种。
整个过程就是用户在登陆的时候,如果选择了记住密码或者一周内免登陆等这个选项的时候,则在用户成功登陆操作完成之后,存储一个实现自动登录的cookie的数据到数据库的用户表里面,作为下次自动登录时验证用。验证通过则自动登录,否则需要输入用户名,密码进行登录。保存的这个cookie值则可以取一个随机码。
具体示例代码如下:
代码如下 | 复制代码 |
$username=trim($_POST['username']); |
另外在访问网站的每个页面时,都要先进行一遍如下函数的检查。
代码如下 | 复制代码 |
//检查用户是否登录 |
以下对 Drupal 的一些缺陷和不足进行罗列和说明,并且也提供一些弥补、改善或者避开的方法,这样以后在遇到这些问题的时候能够更从容一些。
易学性与易用性
Drupal 在用户友好的层面上存在两大“不足”,分别是易学性和易用性。
Drupal 易学性上的不足是先天基因决定,它是面向“开发人员”的工具,而非面向普通用户的产品。要基于 Drupal 搭建一个网站或者是系统,普通用户入手之初最多只能安装和配置一些简单的模块,要想做到像熟手们说的那样“找到模块安装一下就好了”,那是不可能的。
如果想要对系统进行修改或者说是扩展,前期没有投入一定的时间去学习和了解 Drupal 的基本知识,除了面对一大片后台管理链接无所适从之外,新手们还能干什么呢?
Drupal 非常不容易学习,因为扩展的灵活性使其拥有了相对其它系统更为复杂的结构,添加新页面应该使用菜单系统、访问数据库应该使用数据库抽象层、添加修改模版要先学习模版机制,原本在其它系统下的经验到 Drupal 上来统统都不能用了 —— 使用 Drupal 的人少,与它的学习曲线、学习周期严重相关。这是 Drupal 的一个先天不足,但这些“化简为繁”的机制和抽象层最终给 Drupal 提供了无比强大、无可比拟的扩展性和灵活性 —— 所以对于慕名而来的 Drupal 的仰慕者们,Drupal 很强大,但必须要在熟练的人的手上,可以花重金请专业的团队打造世界一流的站点和系统,但切不可抓几个 PHPer 就妄想短时间内驾驭这匹野马。
PS: Drupal 功能性和扩展性的强大,以及学习曲线和周期决定了其自身的价值,一分努力一分收获,请走在 Drupal 之路上的各位谨记!!!
与易学性相同,Drupal 的易用性也是先天不足,一方面是因为它不是面向普通用户“开箱即用”的产品,另一方面是因为在用户体验“能用、易用、好用”的三级标准上,Drupal 的功能在很大一部分程度上都只是“能用”的级别。只实现基本的体验和交互,优点在于能够方便地在其之上添加需要的行为,缺点在于没有一个默认易用的行为,每个站点都需要付出一定的工作量。
易用性是 Drupal 的一项不足,但并非硬伤,相对其它一些不易扩展的CMS或者框架,Drupal 至少能够让我们更快的优先获得功能,至于用户体验和交互,对于熟手来讲也是手到擒来的事。
因为今天时间有限,后面的一些缺陷与不足先简单介绍一下,后续有需要了解的地方大伙再给我发邮件或者是留言咨询吧,先谢过。
兼容性
Drupal 大版本之间不提供向后兼容,即 D7 不向后兼容 D6,D8 不向后兼容 D7。根据 Dries 若干年前的博客(大概是2005年,记不太清楚了),说明了 Drupal 的新版本会选择同时期最新的技术,以保证 Drupal 走在技术的前沿,同时因为不提供向后的兼容,能够更好的保持核心的精简。
对于需要做大版本升级的个人或公司,在此的第一个建议是不要做大版本升级,因为确实必要性不大,但工作量可能惊人的可怕。如果实在要升级,同样从工作量出发,可以先行评估,然后从升级和重建中做出合适的选择。
性能
Drupal 在扩展性和灵活性之间需要做出平衡,模块化的架构和 hook回调系统则是站在扩展性这一边。强大的扩展性会带来性能上的损耗,但 Drupal 通过内置的缓存系统以及整合各种外部缓存、代理、加速来大幅提升性能。
有关扩展与性能的话题,我们在之前的视频里面有提到过,可以找找看。
模版抽象层
Drupal 的页面布局更多是通过区域分配的方式来执行,内容与内容框架(确定内容组织方式的HTML代码结构)混合存在一起,传统前端生成 HTML的方式在 Drupal 中难以得以应用。而内容与内容框架混合的形式也使得 Drupal 主题很难像 WordPress 那样做到主题的复用。
团队协作
Drupal 的团队协作应该算是 Drupal 各种抽象层的副作用,因为整个项目流程与传统网站项目不同,所以协作上也会出现一些难点。不过通过对 Drupal 流程有清晰的了解之后,能够找出不同职能的分界线,通过 Drupal 的方式来进行团队协作,问题就能够得以解决了。
Drupal 配置迁移是什么?很多 Drupaller 对这个话题感到无所适从,新人工作之初并不会意识到这个问题的存在,而意识到这个问题的朋友也不确定怎样正确地进行配置迁移。本文就围绕 Drupal 配置迁移的原因、方式/方法及相关模块较为系统地聊聊这个话题。
如果你被以下问题困扰,仔细阅读本文将会对你有所助益
修改了一些站点配置(如站点名称、标语或任何存在于variables表中的变量值),怎么一次性部署到线上?怎么跟踪每次的修改记录?(大部分情况下你是不是直接在线上修改了:D)
在开发环境中页面布局进行了调整,修改了区块的配置(如位置、显示条件)和内容,怎么样才能快速地部署到线上(是不是手动一个一个去调整,把做过的事情重新再做一遍——这样很无趣,也很费时,还容易遗漏和出错,尤其是当这些配置之前是由其它人配置的,想要再准确地复现将会非常困难)
在开发环境中添加了几个新的字段、内容类型、输入格式、Wysiwyg配置或者视图,不想在线上再手动操作,点鼠标点到手发麻,又应该怎么办?
开发过程中需要大量实际数据,不能直接在线上操作,如何把实际数据从线上迁移到开发环境中?
……
为什么 Drupal 要做配置迁移?
大家都熟悉传统的Web开发,主要工作都是面对代码,不管是PHP、CSS、HTML或JS,几乎所有的工作都是在文件中完成。如果要更新或升级某些功能,做好备份后上传修改过的文件就能完成,So Easy!
对Drupal而言,配置迁移就不那么简单了,因为文件迁移只是 Drupal 配置迁移的一小部分,Drupal 中大部分的配置存在于数据库中。而因为线上环境的数据库时刻在变化,要把开发环境中一部分数据库的内容更新到线上而又不影响线上的内容,可不是一件容易的事。
Drupal将配置存在于数据库中是经常被Drupal老手们诟病的问题之一——最大的缺点是你不能简单地迁移数据库中的某些值或对其实行版本控制,当然这样设计的优点在于方便开发人员进行研发,以及方便使用者通过界面(而不需要修改代码)非常快速地对功能进行调配。(再一次,Drupal选择了灵活性而牺牲了其它东西)
在D8之前,Drupal没有统一的标准来规范大家应该如何存储各自己的配置数据,不同模块的配置格式和存储方式并不相同,因此也就无法通过某种特定的方式一次性迁移出所有配置数据。
(D8开始实施配置管理系统了,从此对配置的管理有了统一的规范和标准,可参见《Drupal 8 配置管理机制及新特性简介》)
而另外一点造成Drupal的配置迁移成为一个难点话题的原因在于,D8之前,Drupal的配置和内容混合存储在数据库中,很难将两者分离开,如果只是通过覆盖数据库的方式来进行操作,无法做到只改变配置而不触及内容,反之亦然。
因为设计上的原因,使得Drupal的配置迁移成了一个难点,针对于它的工作流程和解决方案也就成了一个独立的、不可回避的且颇有意思的话题。
目前有关Drupal配置迁移的处理方式已经非常成熟,D8之前的配置迁移可以参考本文,D8的配置迁移大家去学习其配置管理系统的知识并熟练运用即可。虽然D8之前没有官方统一的标准配置管理体系,但D8配置管理体系的很多理念与本文提及的各种配置迁移方式是相同的,因此学习本文也将会使之后了解D8的配置管理系统变得更为容易一些。
加强 Drupal 配置迁移自动化的优点
相信有很多朋友在做 Drupal 开发时会先在本地做一次,然后到测试环境或生产环境再做一次。当然这也不失为一种方式,对小站点的功能部署还能适用,但对于在线下进行了几周甚至几个月的工作量,再重复做一次的代价可是相当大的——前提还要是每个人都记得整段时间都按什么顺序做了什么配置。
如果大家希望更轻松、更准确、更高效、更简单地完成配置迁移的任务,不妨学会如何让配置迁移更为自行化。
以下是通过各种工具进行自动化配置迁移的一些主要优点:
减轻工作量——大量配置的部署真的可以点鼠标点到手发麻,将大量点击操作简化为上传文件会轻松很多;
降低错误率——人往往是出错的主要原因,让代码来记忆第一步操作可以大大降低出错机率;
版本控制——能够记录每一次配置的变更状况与时间,同时也更容易将配置恢复到某个时间点的备份;
快速部署——站点经不起长时间离线,将数周及数月的更新在数分钟基本数秒钟之内完成会有很爽的成就感;
……
Drupal 常见的配置迁移情况
之所以要谈配置迁移,是因为Web项目至少会有两个环境,即工程师的本地开发环境,和在线运行的生产环境。而通常情况下,标准的Web项目会涉及“开发-测试-线上”,即流行的 Dev-Stage-Prod 模型(也有称Dev-Stage-Live),复杂点的情况还会再加上一个QA环境。也正因为如此,才出现了配置迁移的需要。
在后文中,我们将以 Dev-Stage-Prod 环境模型为来了解 Drupal 的配置迁移方式及方向。因为这正好代表了我们平时的工作流程——工程师在各自的本地进行开发,然后部署到测试环境集中测试,反复修正最后再部署到线上。
Drupal 需要迁移哪些内容以及如何迁移
了解了需要迁移的原因,我们再看看需要迁移的内容。正如前面所说,Drupal 中不同的配置有不同的迁移方式,使用对的工具和对的方法能够达到事半功倍的效果。
迁移项 | 存储位置 | 迁移方式 |
模块、主题 | 模块、主题文件中 | 直接上传文件 |
环境变量 | 数据库中 | 结合 Features 结合 Strongarm 模块打包到文件,然后上传 |
视图、编辑器、内容类型、字段、区块 | 数据库中 | 使用 Features 及 Features Extra 等模块打包到文件,然后上传 |
*术语、用户等配置依赖内容 | 数据库中 | 可使用 Features, UUID 及 UUID Features 等模块打包到文件,然后上传。 但建议先添加到线上环境,然后将数据库下载到本地进行开发会更简单,详见下方 |
不要感觉要记很多东西似的,这里帮你整理一下 —— Drupal 的配置无非就是存在于文件和数据库中,存在文件中的配置很好处理,直接上传就行。而对于存在于数据库中的配置呢?很简单 —— 先转化成文件,然后上传文件。
在举例说明不同配置迁移的最佳实践前,建议大家一定记住下图——代码(配置)由下往上,数据库(内容)由上往下——这是团队协作的基本铁律,以便确保文件和数据库都是由新往旧的方向部署,从源头减少冲突的发生。
(很多人在协作时会问这样的问题,说“我在线上修改了视图的配置,然后线下更新了视图的配置文件,这样要怎么更新呢?”这就是典型因为协作流程不规范而产生的人为冲突,一旦按照规范能够约束文件(配置)、数据库(内容)的更新方向,这类问题基本上便不会出现了。)
回到文章开头提到的几个问题,现在再来看看这些配置迁移流程建议:
站点配置或其它变量迁移 – 使用 Features 模块,结合 Strongarm 模块将要跟踪的变量打包到文件中,然后按 Dev->Stage->Prod 的方向进行更新部署
区块配置迁移 – 使用 Features 模块,结合 Features Extra 模块,将区块的配置及内容打包到文件中,然后按 Dev->Stage->Prod 的方向进行更新部署
内容类型、字段、视图、输入格式、编辑器配置等 – 使用 Features 模块(必要时结合Strongarm)将配置打包到文件中,然后按 Dev->Stage->Prod 的方向进行更新部署
内容数据的更新 – 使用 Backup and Migrate 模块或其它方式导出线上环境的数据库,并按 Prod->Stage->Dev 的方向进行内容更新
Drupal 配置迁移小结
现在看来,Drupal的配置迁移无非是两部分的内容,一部分已经存在于文件(如模块、主题)中的内容,直接上传文件进行更新即可;另一部分存在于数据库中的部分配置(或内容),即通过Features及其它相关模块先将配置导出到文件中,再按更新文件的操作进行即可。
别看关于 Drupal 配置迁移好像写了不少,主要便是掌握 Features 模块的用法和流程,稍加练习几次就会发现真是非常简单。
问题描述:
如果用户输入的数据在未经处理的情况下插入到一条SQL查询语句,那么应用将很可能遭受到SQL注入攻击,正如下面的例子:
代码如下 | 复制代码 |
$unsafe_variable = $_POST['user_input']; mysql_query("INSERT INTO `table` (`column`) VALUES ('" . $unsafe_variable . "')"); |
因为用户的输入可能是这样的:
代码如下 | 复制代码 |
value'); DROP TABLE table;-- |
那么SQL查询将变成如下:
代码如下 | 复制代码 |
INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--') |
应该采取哪些有效的方法来防止SQL注入?
最佳回答(来自Theo):
使用预处理语句和参数化查询。预处理语句和参数分别发送到数据库服务器进行解析,参数将会被当作普通字符处理。这种方式使得攻击者无法注入恶意的SQL。 你有两种选择来实现该方法:
1、使用PDO:
代码如下 | 复制代码 |
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name'); $stmt->execute(array('name' => $name)); foreach ($stmt as $row) { // do something with $row } |
2、使用mysqli:
代码如下 | 复制代码 |
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?'); $stmt->bind_param('s', $name); $stmt->execute(); $result = $stmt->get_result(); while ($row = $result->fetch_assoc()) { // do something with $row } |
PDO
注意,在默认情况使用PDO并没有让MySQL数据库执行真正的预处理语句(原因见下文)。为了解决这个问题,你应该禁止PDO模拟预处理语句。一个正确使用PDO创建数据库连接的例子如下:
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
在上面的例子中,报错模式(ATTR_ERRMODE)并不是必须的,但建议加上它。这样,当发生致命错误(Fatal Error)时,脚本就不会停止运行,而是给了程序员一个捕获PDOExceptions的机会,以便对错误进行妥善处理。 然而,第一个setAttribute()调用是必须的,它禁止PDO模拟预处理语句,而使用真正的预处理语句,即有MySQL执行预处理语句。这能确保语句和参数在发送给MySQL之前没有被PHP处理过,这将使得攻击者无法注入恶意SQL。了解原因,可参考这篇博文:PDO防注入原理分析以及使用PDO的注意事项。 注意在老版本的PHP(<5.3.6),你无法通过在PDO的构造器的DSN上设置字符集,参考:silently ignored the charset parameter。
解析
当你将SQL语句发送给数据库服务器进行预处理和解析时发生了什么?通过指定占位符(一个?或者一个上面例子中命名的 :name),告诉数据库引擎你想在哪里进行过滤。当你调用execute的时候,预处理语句将会与你指定的参数值结合。 关键点就在这里:参数的值是和经过解析的SQL语句结合到一起,而不是SQL字符串。SQL注入是通过触发脚本在构造SQL语句时包含恶意的字符串。所以,通过将SQL语句和参数分开,你防止了SQL注入的风险。任何你发送的参数的值都将被当作普通字符串,而不会被数据库服务器解析。回到上面的例子,如果$name变量的值为 ’Sarah’; DELETE FROM employees ,那么实际的查询将是在 employees 中查找 name 字段值为 ’Sarah’; DELETE FROM employees 的记录。 另一个使用预处理语句的好处是:如果你在同一次数据库连接会话中执行同样的语句许多次,它将只被解析一次,这可以提升一点执行速度。 如果你想问插入该如何做,请看下面这个例子(使用PDO):
代码如下 | 复制代码 |
$preparedStatement = $db->prepare('INSERT INTO table (column) VALUES (:column)'); $preparedStatement->execute(array('column' => $unsafeValue)); |
相关文章
- 获取网站icon,常用最简单的方法就是通过website/favicon.ico来获取,不过由于很多网站都是在页面里面设置favicon,所以此方法很多情况都不可用。 更好的办法是通过google提供的服务来实现:http://www.google.com/s2/favi...2014-06-07
mac下Apache + MySql + PHP搭建网站开发环境
首先为什不自己分别搭建Apache,PHP和MySql的环境呢?这样自己可以了解更多知识,说起来也更酷。可也许因为我懒吧,我是那种“既然有现成的,用就是了”的人。君子生非异也,善假于物也。两千年前的荀子就教导我们,要善于利用工具...2014-06-07- 我要实现的就是下图的这种样式,可参考下面这两个网站的留言板,他们的实现原理都是一样的畅言留言板样式:网易跟帖样式:原理 需要在评论表添加两个主要字段 id 和 pid ,其他字段随意添加,比如文章id、回复时间、回复内容、...2015-11-08
OPPO R9s如何开启Real原声技术?OPPO R9s开启Real原声技术教程
本篇文章介绍了OPPO R9s如何开启Real原声技术的方法,有需要的小伙伴可以进来看一看。 OPPO R9s如何开启Real原声技术?Real原声技术是R9s自带的音质提升技术,开启之后...2016-12-31网站广告怎么投放最好?首屏广告投放类型优化和广告位布局优化的案例
网站广告怎么投放最好?一个网站中广告位置最好的是哪几个地方呢,许多的朋友都不知道如何让自己的网站广告收效最好了,今天我们就一起来看看吧。 在说到联盟优化前,...2016-10-10- 这篇文章主要介绍了JS跨浏览器解析XML应用过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-10-16
- 个人网站建设应该考虑哪些问题呢?这个问题我们先在这里不说,下文会一一列出来,希望这些建义能帮助到各位同学哦。 我相信VIP成员里面有很多站长,每个人几乎都拥有一个...2016-10-10
vivo X9如何查出后台偷跑流量应用?vivo X9查出后台偷跑流量应用的方法
vivo X9如何查看后台流量偷跑的情况?小编教你轻松查到!还不了解的小伙伴快来看看吧! 1)打开手机自带的【i管家】应用,打开后点击【流量监控】选项。(如下图) 2)接着选...2016-12-31- Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。本文我们来讲解Redis的应用场景实例。 C...2016-11-25
- 分享一篇利用论坛签名提升网站权重的方法,在推广中论坛签名也是一种不错的外链推荐的方法,但现在权重越来越低了,有需要的朋友可以看看。 话说有一天在站长网上面看...2016-10-10
- 一、靠前排名成搜索关注的对象 从搜索引擎的角度考虑一下,就不难理解为什么搜索引擎对排名在首页的网站那么慎重,甚至对新进排名在首页的一些网站进行为期一个多月的...2016-10-10
PHP explode()函数的几个应用和implode()函数有什么区别
explode()函数介绍explode() 函数可以把字符串分割为数组。语法:explode(separator,string,limit)。 参数 描述 separator 必需。规定在哪里分割字符串。 string...2015-11-08- Libevent 是一个用C语言编写的、轻量级的开源高性能网络库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,下文我们就一起来看PHP Libevent扩展安装...2016-11-25
- <? $a="变量的值将被带入"; echo <<< help <pre> php中echo <<< 的应用 虽然echo "...";可以断行,但若其中如出现",则仍需做转义 处理。需写做: echo " ...2016-11-25
- 关于如何提高网站的吸引呢,下面我们列出了5点,让你的网站pv大大的提升哦 1、建立一个清晰的网站地图 一个清晰的网站地图可以给你的用户提供一个简介明了的...2017-07-06
- ...2016-09-20
- 第一,网站的内容;请各位站长朋友不要一天到晚只想着出什么好的绝招来推广网站,却忽略了网站的内容;其实网站的内容是极为重要的,因为这是你的本,你的根!网站的内容只有不断...2017-07-06
- 今天小编就为大家分享一篇关于C#网站生成静态页面的实例讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...2020-06-25
- 网站改版了怎么办?很多网站在改版的时候,非常担心用户习惯。 有的担心是合理的,有的担心是多余的。担心之前,先搞清两个问题: 首先,你有没有老用户?有多少老用户?如果...2016-09-20
- 这两个网站的title和description部分关键词有点过于强调,决定弱化这种现象成了我的当务之急,以提高网站在搜索引擎里的品牌形象(搜索引擎返回结果就这两部分)。通过分析...2016-10-10