随着互联网的不断普及,行业网站建设已经成为国内企业提高核心竞争力的主要措施,基于PHP语言开发的动态 网站因拥有数据处理快、优质的信息管理、快捷的执行速度、系统安全度高以及完整性控制等方面的优势而逐渐被广泛应用。文 章从PHP语言的简要介绍入手,以PHP语言进行网站开发模型设计,通过对行业网站的设计目标和开发工具进行分析,以期为 行业网站建设实践提供理论依据。
PHP语言的概述
根据动态网站要求,PHP语言作为一种语言程序,其 专用性逐渐在应用过程中显现,其技术水平的优劣与否将 直接影响网站的运行效率。其特点是具有公开的源代码, 在程序设计上与通用型语言,如C语言相似性较高,因此 在操作过程中简单易懂,可操作性强。同时,PHP语言具 有较高的数据传送处理水平和输出水平,可以广泛应用在 Windows系统及各类Web服务器中。如果数据量较大, PHP语言还可以拓宽链接面,与各种数据库相连,缓解数 据存储、检索及维护压力。随着技术的发展,PHP语言搜搜索引擎还可以量体裁衣,实行个性化服务,如根据客户的喜 好进行分类收集储存,极大提高了数据运行效率。
PHP语言的优势分析与同类型语言相比,PHP语言优势明显:
PHP语言是一种供客户免费使用的语言,即使客户不 同,也无须额外付费,这成为其应用的第一大优势。
PHP语言的编程设计与C语言有较高的相似性,易于 开发人员操作。
PHP语言的受众面积较大,在行业网站建设过程中, 从小型网站到大型网站均可使用。
PHP语言在补丁漏洞升级过程中,核心部分植入简单 易行,且速度快。
PHP语言在数据库应用过程中,可以从数据库调取各 类数据,执行效率高。
应用PHP语言进行网站建设时的注意事项
PHP语言应用过程中,要求开发人员熟悉该语言,特 别是软件版本、特性等诸多环节,否则容易造成冲突,使配置问题难以处理。因此,在网站开发设计过程中,应避免单 独进行环境搭配。
结论
从上述实践性分析可以看出,与其他常用语言相比, PHP语言优势明显。较好的可移植性、可靠性以及较高的 运行效率使PHP语言在当下行业网站建设中独占鳌头。利 用PHP语言进行行业网站设计,能够实现数据库的实时性 更新,网站的日常维护和管理简单易行,进而提高用户的使 用效率。原创文字:来源海洋网络 http://www.hy755.cn/ 版权所有,转载注明出处,并保留本链接
目前,基于PHP的网站开发已经成为目前网站开发的主流,本文猫巷重点从PHP网站攻击与安全防范方面进行探究,旨在减少网站漏洞,希望对大家有所帮助!
网站漏洞一:常见PHP网站漏洞安全。
Session文件漏洞Session攻击是黑客最常用到的攻击手段之一。当一个用户访问某一个网站时,为了免客户每进人一个页面都要输人账号和密码,PHP设置了Session和Cookie用于方便用户的使用和访向。SQL注入漏洞在进行网站开发的时候, 程序员由于对用户输人数据缺乏全面判断或者过滤不严导致服务器执行一些恶意信息,比如用户信息查询等。黑客可以根据恶意程序返回的结果获取相应的信息。这就是所谓的SQL注入漏洞。脚本执行漏洞脚本执行漏洞常见的原因是由于程序员在开发网站时对用户提交的URL参数过滤较少引起的,用户提交的URL可能包含恶意代码导致跨站脚本攻击。脚本执行漏洞在以前的PHP网站中经常存在,但是随着PHP版本的升级,这些间题已经减少或者不存在了。全局变量漏洞PHP中的变量在使用的时候不像其他开发语言那样需要事先声明,PHP中的变量可以不经声明就直接使用,使用的时候系统自动创建,而且也不需要对变量类型进行说明,系统会自动根据上下文环境自动确定变量类型。这种方式可以大大减少程序员编程中出错的概率,使用起来非常的方便。文件漏洞文件漏洞通常是由于网站开发者在进行网站设计时对外部提供的数据缺乏充分的过滤导致黑客利用其中的漏洞在Web进程上执行相应的命令。假如在lsm.php中包含这样一段代码:include($b.”/aaa.php”.),这对黑客来说,可以通过变量$b来实现远程攻击,可以是黑客自已的代码,用来实现对网站的攻击。可以向服务器提交a.php include=http://127.0.0. 1/b.php,然后执行b.php的指令。
二:PHP常见漏洞的防范措施。
对于Session漏洞的防范从前面的分析可以知道,Session攻击最常见的就是会话劫持,也就是黑客通过各种攻击手段获取用户的Session ID,然后利用被攻击用户的身份来登录相应网站。为此,这里可以用以下几种方法进行防范:一是定期更换Session ID,更换Session ID可以用PHP自带函数来实现;二是更换Session名称,通常情况下Session的默认名称是PHPSESSID,这个变量一般是在cookie中保存的,如果更改了它的名称,就可以阻档黑客的部分攻击;三是对透明化的Session ID进行关闭处理,所谓透明化也就是指在http请求没有使用cookies来制定Session id时,Sessioin id使用链接来传递.关闭透明化Session ID可以通过操作PHP.ini文件来实现;四是通过URL传递隐藏参数,这样可以确保即使黑客获取了session数据,但是由于相关参数是隐藏的,它也很难获得Session ID变量值。对于SQL注入漏洞的防范黑客进行SQL注入手段很多,而且灵活多变,但是SQL注人的共同点就是利用输入过滤漏洞。因此,要想从根本上防止SQL注入,根本解决措施就是加强对请求命令尤其是查询请求命令的过滤。具体来说,包括以下几点:一是把过滤性语句进行参数化处理,也就是通过参数化语句实现用户信息的输入而不是直接把用户输入嵌入到语句中。二是在网站开发的时候尽可能少用解释性程序,黑客经常通过这种手段来执行非法命令;三是在网站开发时尽可能避免网站出现bug,否则黑客可能利用这些信息来攻击网站;仅仅通过防御SQL注入还是不够的,另外还要经常使用专业的漏洞扫描工具对网站进行漏洞扫描。对于脚本执行漏洞的防范黑客利用脚本执行漏洞进行攻击的手段是多种多样的,而且是灵活多变的,对此,必须要采用多种防范方法综合的手段,才能有效防止黑客对脚本执行漏洞进行攻击。这里常用的方法方法有以下四种。一是对可执行文件的路径进行预先设定。可以通过safe_moade_exec_dir来实现;二是对命令参数进行处理,一般用escapeshellarg函数实现;三是用系统自带的函数库来代替外部命令;四是在操作的时候进可能减少使用外部命令。4.对于全局变量漏洞的防范对于PHP全局变量的漏洞问题,以前的PHP版本存在这样的问题,但是随着PHP版本升级到5.5以后,可以通过对php.ini的设置来实现,设置ruquest_order为GPC。另外在php.ini配置文件中,可以通过对 Magic _quotes_runtime进行布尔值设置是否对外部引人的数据中的溢出字符加反斜线。为了确保网站程序在服务器的任何设置状态下都能运行。可以在整个程序开始的时候用get_magic_quotes_runtime检测设置状态决定是否要手工处理,或者在开始(或不需要自动转义的时候)用set_magic_quotes_runtime(0)关掉。5.对于文件漏洞的防范对于PHP文件漏洞可以通过对服务器进行设置和配置来达到防范目的。这里具体的操作如下: 一是把PHP代码中的错误提示关闭,这样可以避免黑客通过错误提示获取数据库信息和网页文件物理路径;二是对open_basedir尽心设置,也就是对目录外的文件操作进行禁止处理;这样可以对本地文件或者远程文件起到保护作用,防止它们被攻击,这里还要注意防范Session文件和上载文件的攻击;三是把safe-made设置为开启状态,从而对将要执行的命令进行规范,通过禁止文件上传,可以有效的提高PHP网站的安全系数。
欢迎大家关注这个百家号,作为一个技术型的百家号,请大家多多指导,另外可以去我的博客踩踩-->猫巷の博客,百度猫巷或者直接访问lovyou.top,emmm~~~,爱你们,谢谢大家支持。
很多公司进行网站建设时采用了PHP语言作为开发语言,大部分的网站开发公司也都有PHP开发团队,PHP作为现流行的开发语言之一,深受广大开发者喜爱,也得到了很多公司的认可,然而随着PHP越走越远各种开源系统也百家齐放,什么开源网站管理系统,开源办公OS系统,开源商城系统,开源微信、小程序管理系统等等。
那么对于一般的企业网站或者网站带点少许的需求比如:前台分离,多语言开发,数据管理,数据查询等等,企业该如何选择开发的方式呢?
云智总结了现在市面比较流行改的开发方式,这些系统和开发方式企业可以根据自己的实际需求进行选择。
基于网络上开源系统进行二次开发
网络上老牌的开源系统有不少,DEDEcms、EmpireCMS、PHPcms、WordPress等等,市场占有率不少,成熟的架构和功能积累保证了系统安全和实用性,但是系统迭代漏洞比较多,前三个是国内的WP是国外的,EmpireCMS是安全的但是系统体量太大,二次开发要求开发者有一定的基础,这些系统的UI相对WordPress好点但不太适合国人使用习惯后期使用比较麻烦。
这种采用成熟系统的开发模式有点是比较快,但是后期漏洞安全是问题,还有万一哪天漏忘记补上那就悲催了,因为你的结构被人一清二楚。
基于一些程序的框架进行一次开发
说起款国内比较出名PHP框架ThinkPHP简称TP,收到不少项目和开发人员的认可,不过漏洞也挺让人头疼的,再有就是YII、laravel、CI等一大批国外优秀的框架。
采用这些框架进行网站开发的好处就是产品功能的可塑性比较强,比较适合网站配合上一些业务逻辑系统。
基于商业公司的封闭式产品二次开发
一些外包公司有自己的专业管理系统,这些系统并没有在线发布属于内部产品,相对来说比较安全,能够满足大部分企业的需求使用,是企业进行网站开发的首先。
以上三种开发形式企业可以酌情选择,当然不同的开发模式网站开发的费用也是不一样的。
PHP一直被唱衰,特别是某一些培训机构为了推python、java等语言的培训,总是搞一些编程语言排行榜,误导编程初学者,给初学者造成PHP不行了的印象。是否PHP真的在走下坡路?PHP语言到底市场份额占有多少?
不妨根据 W3Techs 提供的数据和报告,看看 PHP 最新的使用统计和市场定位情况。W3Techs 是国外一个专门调查 Web 技术的网站,提供有关 Web 各种技术的使用情况信息。
来源地址:https://w3techs.com/technologies/overview/programming_language
以上是W3Techs提供的2019年12月6号的统计数据。
是的,你没有看错!PHP在WEB网站服务器端使用的编程语言所占份额高达78.9%,稳居第一!将排在第二位的ASP.NET和第三位的JAVA远远甩在身后。
那有人又开始杠了,你只是统计的一个月的,不具有代表性,那我们再来看看最近一年的情况。
(WEB服务器端编程语言使用情况统计)
(折线图形式)
上图我们可以看到PHP语言在WEB服务器端语言中基本稳定保持在79%,ASP.NET有小幅度下滑,Java小幅上升。
总而言之:
PHP是世界上最好的语言,没有之一!不是梗,也不是空穴来风。PHP是免费开源的、WEB开发全球使用最多、生态最好、维护成本也是最低的一种网站服务端开发语言,所以做网站编程开发首选肯定是PHP,PHP也是学习周期最短,入门最容易的一门编程语言,不像Java、Python、.NET等需要一定的学历,另外也是最好找工作的一门语言。
我们再来看看有哪些知名的网站使用的是PHP语言。
全部使用PHP的网站
php中文网
Smzdm
Asus
Nba
Pulzo
Getpocket
部分使用 PHP 的热门网站
Wikipedia
Vk
WordPress
Ettoday
Instructure
腾讯
新浪
百度贴吧
网易
360
宝宝树
那我们学习PHP,要学习哪个版本呢?
我们来看下具体的统计:
从图中可以看出,PHP 5 和 PHP 7 是目前的主流。尤其是 PHP 5,大有还能再战几年的势头,至于 PHP 4 和 3 可以说是已经被抛弃了。
从PHP7开始,性能更是质的提高!最新一个版本PHP7.4也在11月底公布了,具体可参考《PHP 7.4.0刚刚发布!一起看看有哪些新特性》。
PHP8也即将发布,每个新版本都朝着更好的PHP迈出了又一步,届时php会走的更远!
导语 : 这次带来的推荐是,“世界上最好的语言”PHP。PHP 的语法融合了各式各样语言的语法优点,结合自身独创的语法,以其高效率,简洁的特点而深受广大程序员的喜爱。现在我就带大家,来探索互联网深处,有哪些免费而优质的教程。
慕课网php入门篇
慕课网,可以说的算是一个耳熟能详的名字了,里面优质的教程不知有多少。这次我先给大家介绍的就是慕课网的视频教程,php入门篇。在这篇教程中,把php的基础教程都详尽的讲了出来。而学习到后面,还有php进阶篇。值得学习。
php中文网
php中文网是一个专门面向php学习热爱者的网站,比较权威。里面除了我推荐的免费文档教程,还有工具推荐,社区问答,热点新闻等等,可以说的算是非常全面了。推荐php学习爱好者在此长期发展。
w3c网站
说到文档教程,w3cschool当然是肯定又要讲的名字了。和以前讲的一样,w3c的教程适合在查阅的时候阅读,里面的教程广,但是讲的不详细。需要些耐心,当你全部读完的时候,相信你一定能收获颇多。
php100教程
这个网站可以说的上是一个非常小众的网站了,跟别的文档教程不同,它有很多函数库,适合学习在后面学习的时候阅读。如果这个你也能耐心的读完,那么你就可以将网站的一些小功能实现了。
php完全自学手册
阿里云大学,听名字就很厉害,哈哈。而这个php完全自学手册,非常不错,如果是第一次学习,建议可以先阅读这个教程,比较好理解。而且也非常全面,值得推荐。
尽量完整的需求方案,具体到功能上:建模结构UML,建立数据库: 1、建立的表名、字段名要与他的功能有关系。 2、根据结构建立数据库表,原则是不定项内容一定要分表。 3、字段类型要考虑内容是否够用就够就好,选择适合的类型INT Varchar Date(4)设计HTML文件和脚本的实现 根据模和数据库来设计页面是个很科学的方法,当然有的时候有人喜欢根据模型设计页面,数据库基于页面设计,都是可以的。 设计页面时要考虑到每个细节,包括提示消息页面,错误页面。(5)PHP代码的书写1、先建立底层结构和文件夹(如果是大型的网站同样设计一个文件UMML)2、基础功能分类关联,以便今后代码引用。3、代码的书写,注意简洁性和函数的使用,内部函数能实现的尽量使用内部函数。4、在部分关键位置加以代码注释。(6)程序的测试和修正1、对于发现的BUG不能就解决BUG而解决,要处于完整程序考虑。避免收之东隅收之桑榆。2、对于解决过的BUG已经要详细记录,以便日后更新。多人开发应该注意什么使用版本服务器:CVS、SVN...功能:1、单个文件历史版本的记录和恢复2、文件的锁定和更新3、单个或多个文件程序之间的沟通4、保护程序的安全性不受单个程序的误操作而丢失
尽量完整的需求方案,具体到功能上:建模结构UML,建立数据库: 1、建立的表名、字段名要与他的功能有关系。 2、根据结构建立数据库表,原则是不定项内容一定要分表。 3、字段类型要考虑内容是否够用就够就好,选择适合的类型INT Varchar Date(4)设计HTML文件和脚本的实现 根据模和数据库来设计页面是个很科学的方法,当然有的时候有人喜欢根据模型设计页面,数据库基于页面设计,都是可以的。 设计页面时要考虑到每个细节,包括提示消息页面,错误页面。
(5)PHP代码的书写1、先建立底层结构和文件夹(如果是大型的网站同样设计一个文件UMML)2、基础功能分类关联,以便今后代码引用。3、代码的书写,注意简洁性和函数的使用,内部函数能实现的尽量使用内部函数。4、在部分关键位置加以代码注释。(6)程序的测试和修正1、对于发现的BUG不能就解决BUG而解决,要处于完整程序考虑。避免收之东隅收之桑榆。2、对于解决过的BUG已经要详细记录,以便日后更新。多人开发应该注意什么使用版本服务器:CVS、SVN...功能:1、单个文件历史版本的记录和恢复2、文件的锁定和更新3、单个或多个文件程序之间的沟通4、保护程序的安全性不受单个程序的误操作而丢失
文章来源:昆明网站建设专业品牌——找北网络科技(zhaobeikj.com)
PHP编程语言是目前编程语言中最热门的编程之一,PHP应用领域最多的是WEB开发,PHP和mysql结合可以做出完美的网站,目前大多WEB网站都会选择PHP开发,开源成本低,高效质量好。
学习PHP编程其实比较容易,如果你学过HTML、CSS、JavaScript等前端语言将会帮助更快了解和学习PHP编程,PHP主要是可以直接嵌入HTML开发。
很多新手PHP程序员都会选择自学PHP编程,首先,PHP配置环境很简单,有一键生成的开发集成环境,比如phpstudy,WampServer等。
其次,PHP语法简单容易掌握,如果你学过C语言或java编程,你就会知道PHP不需要记太多的东西,直接嵌入HTML页面开发。
PHP输出Hello World:
<!DOCTYPE html> <html> <body> <?php echo "Hello World!"; ?> </body> </html>
java输出Hello World:
publicclassHelloWorld{publicstaticvoidmain(String[]args){System.out.println("Hello World"); }}
最后,学习PHP编程很快可以进入工作状态。PHP需要掌握技能并不是很多,开源代码很多都是直接复制别人的代码,所有的PHP源代码事实上都可以得到。
如果你目前正在自学PHP,这里推荐几个php自学网站:第一PHP社区(很多技术问题),PHP中文网(推荐新手教程),CSDN(技术大神文章,分享技术)、PHPChina开发者社区、
责任编辑:常青春科技
一点PHP
浙江一点PHP博客www.yidianphp.com是由一点博主个人创建,其目的是分享关于互联网编程知识以及博主从事互联网工作经验。只为帮助更多热爱IT编程的开发者,为中国互联网IT做一份贡献!
本站目前分享的技术有PHP,Java,Python,前端,数据库,Linux,SEO等方面,博主主要从事PHP工作,不过对其他知识也有涉及。通常帮助一个客户做一个项目,可能会用到很多方面的编程知识,博主认为每一门语言都有各自的优缺点,只有将其融会贯通,结合使用在项目中方才是最好的。
还是那句话这里是专为网络编程爱好者打造的PHP技术以及其他编程IT技术的博客,这里只有干货和经验!
可以点击上方一点PHP进入熊掌号查看获得相关详情。
第一节 动态网站
概念
误区:不是指网站当中包含动态图片、滚动图等动态效果
正解:采用数据库技术开发的网站,网页上的内容都是通过数据库提取出来动态更新的
B/S软件
通过浏览器和服务器(Browser / Server)进行通信的软件,客户端给服务器发请求,服务器处理客户请求返回结果
优势:不用下载,不用更新,打开网页,直接使用
劣势:功能受限(受浏览器环境限制)
使用技术
前端:html+css+javascript
后端:php、asp、java
数据库:MySQL、SQLServer、ORACLE、DB2
PHP第二节 动态网站开发所需构件
web前端开发
HTML
CSS
javascript
浏览器
Web后端开发(服务器端)
web服务器:Apache、IIS、Tomcat…
数据库:MySQL、MariaDB、Oracle、SQL Server…
服务器端编程语言:PHP、ASP、JSP…
html第三节 php语言简介
PHP(原名Personal Home Page的缩写,已经正式更名为 "PHP: Hypertext Preprocessor",中文名:“超文本预处理器”)是一种通用开源脚本语言。语法吸收了C语言、Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域。PHP 独特的语法混合了C、Java、Perl以及PHP自创的语法。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML文档中,执行效率很高。
php的诞生
1994年Rasmus Lerdorf设计了PHP的第一个版本PHP1.0,并于1995年将其通过社区发布。1996年又设计了PHP2,1998年,由于Zeev Suraski和Andi Gutmans当时正在做毕业设计,需要一个用于开发Web程序的语言,他们也考虑了asp和jsp,但由于ASP只能运行在Windows平台,而JSP又过于复杂,因此,他们最后选择了PHP,但他们发现,PHP的功能当时还十分有限,因此,他们决定为PHP重新编写底层的解析程序,这就是PHP的第一个被广泛使用的版本----PHP3.0。
codephp的优点
PHP 是最好的语言,php和最好的语言几乎没有关系。一般用来讽刺一些没见过世面,把自己归属于某一种编程语言的语言教徒。
事实上每一门语言都有其设计的灵魂,有它的取舍。很难说什么是最好的。比起做个脑残粉总是鼓吹自己擅长的语言,不如多学几门语言,开阔视野。
PHP可能不是世界上最好的语言,但他一定是最适合新手学习编程的入门语言,也是进入Web开发领域的绝佳语言。
简单易学
既能面向过程,又能面向对象,安装后各种扩展集一身,包括但不限于mysql、json、mbstr等,方便至极。html和PHP混写,执行效率很高,最新版本都内置了小型webserver(连apache都不用)。
日臻完善
语言创建者积极上进优化。各大php论坛非常活跃,语言bug全世界的程序员和你一起修复。
框架成熟
框架层出不穷,国外Ci、laravel、kohana、zf,国内thinkphp功能完善,敏捷开发就靠它!!
使用广泛
最重要的是大小公司都用,全球前100万的站点中,有70%左右的站点用PHP开发,找工作不愁啊!!!!
php的缺点
标准库的函数名、参数顺序实在是难以预测
例如:字符串操作系列函数,strpos、strcspn里两个词素没有任何分隔符,到了strreplace、strrepeat却又冒出了下划线
协调性和可靠性
例如:变量名是大小写敏感的,函数名和类名却是大小写不敏感的
奇异的写法
例如:数组末尾添加一个元素, $arr[] = 1
PHP的异常捕获系统非常异常
很难说清楚到底哪些情况会抛出异常哪些并不会
404第四节 环境配置
集成环境
要想使用这门语言,需要搭配相应的开发环境,主要包括:
Apache web服务器
MySQL 数据库
PHP 语言引擎
以上三个模块可以分别安装,再进行相关的配置(手动安装配置相对复杂)。通常使用以上三者的集成环境进行快速部署:
WAMP:Window操作系统 LAMP:Linux操作系统 MAMP:苹果MAC操作系统
以上三个集成环境针对不同操作系统,下载安装后,开发环境就已经自动搭建好了。
以WAMP为例,首先,需要在网站上下载相应的软件到本地电脑。 安装成功,右下角 W 的图标为绿色
运行原理
get请求 :从服务器上获取数据
post请求:向服务器提交数据
数据库配置文件
配置文件是每一项服务的核心,配置文件缺失或修改错误,将导致服务无法正常运行
Apache服务配置文件:D:\wamp64\bin\apache\apache2.4.23\conf\httpd.conf
MySQL服务配置文件:D:\wamp64\bin\mysql\mysql5.7.14\my.ini
PHP模块配置文件:D:\wamp64\bin\apache\apache2.4.23\bin\php.ini
注意:配置文件修改后,必须重启服务
www目录
www目录在wamp目录下,是网站的根目录,开发的所有文件,都要放在www目录中,通过浏览器输入localhost访问本地服务器
localhost
本地服务器,安装了wamp软件的你的电脑,既是客户机,又是服务器,通过浏览器访问的是你本地的服务器,故名称为 localhost
各位朋友大家好,今天给大家带来的是
php爬虫采集类-phpQuery:支持抓取网站,非常强大的php类库!
它是一款基于PHP服务端开源的项目,可以让PHPer轻松处理DOM文档内容,比如可以获取某网站的头条信息。更有意思的是,它采用了jQuery的思想,可以像使用jQuery一样处理页面内容,获取你想要的页面信息。
由于源码比较长,有想要文件版源码的同学可以来我的PHP学习交流裙: 157531900 每天都会上传一些类库,技术分享!欢迎各路小白和大神的加入!
好了,废话不多说,上源码!
<?php
/**
* phpQuery is a server-side, chainable, CSS3 selector driven
* Document Object Model (DOM) API based on jQuery JavaScript Library.
*
* @version 0.9.5
* @link http://code.google.com/p/phpquery/
* @link http://phpquery-library.blogspot.com/
* @link http://jquery.com/
* @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @package phpQuery
*/
// class names for instanceof
// TODO move them as class constants into phpQuery
define('DOMDOCUMENT', 'DOMDocument');
define('DOMELEMENT', 'DOMElement');
define('DOMNODELIST', 'DOMNodeList');
define('DOMNODE', 'DOMNode');
/**
* DOMEvent class.
*
* Based on
* @link http://developer.mozilla.org/En/DOM:event
* @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
* @package phpQuery
* @todo implement ArrayAccess ?
*/
class DOMEvent {
/**
* Returns a boolean indicating whether the event bubbles up through the DOM or not.
*
* @var unknown_type
*/
public $bubbles = true;
/**
* Returns a boolean indicating whether the event is cancelable.
*
* @var unknown_type
*/
public $cancelable = true;
/**
* Returns a reference to the currently registered target for the event.
*
* @var unknown_type
*/
public $currentTarget;
/**
* Returns detail about the event, depending on the type of event.
*
* @var unknown_type
* @link http://developer.mozilla.org/en/DOM/event.detail
*/
public $detail; // ???
/**
* Used to indicate which phase of the event flow is currently being evaluated.
*
* NOT IMPLEMENTED
*
* @var unknown_type
* @link http://developer.mozilla.org/en/DOM/event.eventPhase
*/
public $eventPhase; // ???
/**
* The explicit original target of the event (Mozilla-specific).
*
* NOT IMPLEMENTED
*
* @var unknown_type
*/
public $explicitOriginalTarget; // moz only
/**
* The original target of the event, before any retargetings (Mozilla-specific).
*
* NOT IMPLEMENTED
*
* @var unknown_type
*/
public $originalTarget; // moz only
/**
* Identifies a secondary target for the event.
*
* @var unknown_type
*/
public $relatedTarget;
/**
* Returns a reference to the target to which the event was originally dispatched.
*
* @var unknown_type
*/
public $target;
/**
* Returns the time that the event was created.
*
* @var unknown_type
*/
public $timeStamp;
/**
* Returns the name of the event (case-insensitive).
*/
public $type;
public $runDefault = true;
public $data = null;
public function __construct($data) {
foreach($data as $k => $v) {
$this->$k = $v;
}
if (! $this->timeStamp)
$this->timeStamp = time();
}
/**
* Cancels the event (if it is cancelable).
*
*/
public function preventDefault() {
$this->runDefault = false;
}
/**
* Stops the propagation of events further along in the DOM.
*
*/
public function stopPropagation() {
$this->bubbles = false;
}
}
/**
* DOMDocumentWrapper class simplifies work with DOMDocument.
*
* Know bug:
* - in XHTML fragments, <br /> changes to <br clear="none" />
*
* @todo check XML catalogs compatibility
* @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
* @package phpQuery
*/
class DOMDocumentWrapper {
/**
* @var DOMDocument
*/
public $document;
public $id;
/**
* @todo Rewrite as method and quess if null.
* @var unknown_type
*/
public $contentType = '';
public $xpath;
public $uuid = 0;
public $data = array();
public $dataNodes = array();
public $events = array();
public $eventsNodes = array();
public $eventsGlobal = array();
/**
* @TODO iframes support http://code.google.com/p/phpquery/issues/detail?id=28
* @var unknown_type
*/
public $frames = array();
/**
* Document root, by default equals to document itself.
* Used by documentFragments.
*
* @var DOMNode
*/
public $root;
public $isDocumentFragment;
public $isXML = false;
public $isXHTML = false;
public $isHTML = false;
public $charset;
public function __construct($markup = null, $contentType = null, $newDocumentID = null) {
if (isset($markup))
$this->load($markup, $contentType, $newDocumentID);
$this->id = $newDocumentID
? $newDocumentID
: md5(microtime());
}
public function load($markup, $contentType = null, $newDocumentID = null) {
// phpQuery::$documents[$id] = $this;
$this->contentType = strtolower($contentType);
if ($markup instanceof DOMDOCUMENT) {
$this->document = $markup;
$this->root = $this->document;
$this->charset = $this->document->encoding;
// TODO isDocumentFragment
$loaded = true;
} else {
$loaded = $this->loadMarkup($markup);
}
if ($loaded) {
// $this->document->formatOutput = true;
$this->document->preserveWhiteSpace = true;
$this->xpath = new DOMXPath($this->document);
$this->afterMarkupLoad();
return true;
// remember last loaded document
// return phpQuery::selectDocument($id);
}
return false;
}
protected function afterMarkupLoad() {
if ($this->isXHTML) {
$this->xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml");
}
}
protected function loadMarkup($markup) {
$loaded = false;
if ($this->contentType) {
self::debug("Load markup for content type {$this->contentType}");
// content determined by contentType
list($contentType, $charset) = $this->contentTypeToArray($this->contentType);
switch($contentType) {
case 'text/html':
phpQuery::debug("Loading HTML, content type '{$this->contentType}'");
$loaded = $this->loadMarkupHTML($markup, $charset);
break;
case 'text/xml':
case 'application/xhtml+xml':
phpQuery::debug("Loading XML, content type '{$this->contentType}'");
$loaded = $this->loadMarkupXML($markup, $charset);
break;
default:
// for feeds or anything that sometimes doesn't use text/xml
if (strpos('xml', $this->contentType) !== false) {
phpQuery::debug("Loading XML, content type '{$this->contentType}'");
$loaded = $this->loadMarkupXML($markup, $charset);
} else
phpQuery::debug("Could not determine document type from content type '{$this->contentType}'");
}
} else {
// content type autodetection
if ($this->isXML($markup)) {
phpQuery::debug("Loading XML, isXML() == true");
$loaded = $this->loadMarkupXML($markup);
if (! $loaded && $this->isXHTML) {
phpQuery::debug('Loading as XML failed, trying to load as HTML, isXHTML == true');
$loaded = $this->loadMarkupHTML($markup);
}
} else {
phpQuery::debug("Loading HTML, isXML() == false");
$loaded = $this->loadMarkupHTML($markup);
}
}
return $loaded;
}
protected function loadMarkupReset() {
$this->isXML = $this->isXHTML = $this->isHTML = false;
}
protected function documentCreate($charset, $version = '1.0') {
if (! $version)
$version = '1.0';
$this->document = new DOMDocument($version, $charset);
$this->charset = $this->document->encoding;
// $this->document->encoding = $charset;
$this->document->formatOutput = true;
$this->document->preserveWhiteSpace = true;
}
protected function loadMarkupHTML($markup, $requestedCharset = null) {
if (phpQuery::$debug)
phpQuery::debug('Full markup load (HTML): '.substr($markup, 0, 250));
$this->loadMarkupReset();
$this->isHTML = true;
if (!isset($this->isDocumentFragment))
$this->isDocumentFragment = self::isDocumentFragmentHTML($markup);
$charset = null;
$documentCharset = $this->charsetFromHTML($markup);
$addDocumentCharset = false;
if ($documentCharset) {
$charset = $documentCharset;
$markup = $this->charsetFixHTML($markup);
} else if ($requestedCharset) {
$charset = $requestedCharset;
}
if (! $charset)
$charset = phpQuery::$defaultCharset;
// HTTP 1.1 says that the default charset is ISO-8859-1
// @see http://www.w3.org/International/O-HTTP-charset
if (! $documentCharset) {
$documentCharset = 'ISO-8859-1';
$addDocumentCharset = true;
}
// Should be careful here, still need 'magic encoding detection' since lots of pages have other 'default encoding'
// Worse, some pages can have mixed encodings... we'll try not to worry about that
$requestedCharset = strtoupper($requestedCharset);
$documentCharset = strtoupper($documentCharset);
phpQuery::debug("DOC: $documentCharset REQ: $requestedCharset");
if ($requestedCharset && $documentCharset && $requestedCharset !== $documentCharset) {
phpQuery::debug("CHARSET CONVERT");
// Document Encoding Conversion
// http://code.google.com/p/phpquery/issues/detail?id=86
if (function_exists('mb_detect_encoding')) {
$possibleCharsets = array($documentCharset, $requestedCharset, 'AUTO');
$docEncoding = mb_detect_encoding($markup, implode(', ', $possibleCharsets));
if (! $docEncoding)
$docEncoding = $documentCharset; // ok trust the document
phpQuery::debug("DETECTED '$docEncoding'");
// Detected does not match what document says...
if ($docEncoding !== $documentCharset) {
// Tricky..
}
if ($docEncoding !== $requestedCharset) {
phpQuery::debug("CONVERT $docEncoding => $requestedCharset");
$markup = mb_convert_encoding($markup, $requestedCharset, $docEncoding);
$markup = $this->charsetAppendToHTML($markup, $requestedCharset);
$charset = $requestedCharset;
}
} else {
phpQuery::debug("TODO: charset conversion without mbstring...");
}
}
$return = false;
if ($this->isDocumentFragment) {
phpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'");
$return = $this->documentFragmentLoadMarkup($this, $charset, $markup);
} else {
if ($addDocumentCharset) {
phpQuery::debug("Full markup load (HTML), appending charset: '$charset'");
$markup = $this->charsetAppendToHTML($markup, $charset);
}
phpQuery::debug("Full markup load (HTML), documentCreate('$charset')");
$this->documentCreate($charset);
$return = phpQuery::$debug === 2
? $this->document->loadHTML($markup)
: @$this->document->loadHTML($markup);
if ($return)
$this->root = $this->document;
}
if ($return && ! $this->contentType)
$this->contentType = 'text/html';
return $return;
}
protected function loadMarkupXML($markup, $requestedCharset = null) {
if (phpQuery::$debug)
phpQuery::debug('Full markup load (XML): '.substr($markup, 0, 250));
$this->loadMarkupReset();
$this->isXML = true;
// check agains XHTML in contentType or markup
$isContentTypeXHTML = $this->isXHTML();
$isMarkupXHTML = $this->isXHTML($markup);
if ($isContentTypeXHTML || $isMarkupXHTML) {
self::debug('Full markup load (XML), XHTML detected');
$this->isXHTML = true;
}
// determine document fragment
if (! isset($this->isDocumentFragment))
$this->isDocumentFragment = $this->isXHTML
? self::isDocumentFragmentXHTML($markup)
: self::isDocumentFragmentXML($markup);
// this charset will be used
$charset = null;
// charset from XML declaration @var string
$documentCharset = $this->charsetFromXML($markup);
if (! $documentCharset) {
if ($this->isXHTML) {
// this is XHTML, try to get charset from content-type meta header
$documentCharset = $this->charsetFromHTML($markup);
if ($documentCharset) {
phpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'");
$this->charsetAppendToXML($markup, $documentCharset);
$charset = $documentCharset;
}
}
if (! $documentCharset) {
// if still no document charset...
$charset = $requestedCharset;
}
} else if ($requestedCharset) {
$charset = $requestedCharset;
}
if (! $charset) {
$charset = phpQuery::$defaultCharset;
}
if ($requestedCharset && $documentCharset && $requestedCharset != $documentCharset) {
// TODO place for charset conversion
// $charset = $requestedCharset;
}
$return = false;
if ($this->isDocumentFragment) {
phpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'");
$return = $this->documentFragmentLoadMarkup($this, $charset, $markup);
} else {
// FIXME ???
if ($isContentTypeXHTML && ! $isMarkupXHTML)
if (! $documentCharset) {
phpQuery::debug("Full markup load (XML), appending charset '$charset'");
$markup = $this->charsetAppendToXML($markup, $charset);
}
// see http://pl2.php.net/manual/en/book.dom.php#78929
// LIBXML_DTDLOAD (>= PHP 5.1)
// does XML ctalogues works with LIBXML_NONET
// $this->document->resolveExternals = true;
// TODO test LIBXML_COMPACT for performance improvement
// create document
$this->documentCreate($charset);
if (phpversion() < 5.1) {
$this->document->resolveExternals = true;
$return = phpQuery::$debug === 2
? $this->document->loadXML($markup)
: @$this->document->loadXML($markup);
} else {
/** @link http://pl2.php.net/manual/en/libxml.constants.php */
$libxmlStatic = phpQuery::$debug === 2
? LIBXML_DTDLOAD|LIBXML_DTDATTR|LIBXML_NONET
: LIBXML_DTDLOAD|LIBXML_DTDATTR|LIBXML_NONET|LIBXML_NOWARNING|LIBXML_NOERROR;
$return = $this->document->loadXML($markup, $libxmlStatic);
// if (! $return)
// $return = $this->document->loadHTML($markup);
}
if ($return)
$this->root = $this->document;
}