php怎么写重写?php方法重写介绍
方法的重写/方法的覆盖(override)
当一个父类知道所有的子类都有一个方法,但是父类不能确定该方法究竟如何写,
可以让子类去覆盖这个方法,具体用法如下:
<?php
//抽象一个Animal类
class Animal{
public $name;
protected $price;
function cry(){
echo "不知道动物怎么叫..";
echo "
";}
}
class Dog extends Animal{
//覆盖父类中的 cry()方法
function cry(){
echo "小狗汪汪叫..";
echo "
";}
}
class Pig extends Animal{
//覆盖父类中的 cry()方法
function cry(){
echo "小猪哼哼叫..";
echo "
";}
}
//创建一个只狗
$animal=new Animal();
$animal->cry();
$dog1=new Dog();
$dog1->cry();
$pig1=new Pig();
$pig1->cry();
?>
代码如下 | 复制代码 |
关于方法重写细节讨论:
方法重写就是子类有一个方法,和父类的某个方法的名称、参数个数一样,那么我们就说子类的这个方法重写了父类的那个方法。
1. 要实现重写,要求 子类的那个方法的名字和参数个数一摸一样,但是并不要求参数的名称一样.
2. 如果子类要去调用父类的某个方法(public / protected) 则可以使用 parent::方法名(参数..) , 父类名::方法名(参数...)
3. 在实现方法覆盖的时候,访问修饰符可以不一样 //但是必须满足: 子类的访问范围>=父类的访问范围
注意:当父类的函数为私有(private)类型时,不能覆盖,因为父类为私有该函数根本不能继承。
代码如下 | 复制代码 |
// 多态体现在什么地方? // class Animal{ // public function cry(){ // echo '动物叫唤..'; // } // } // class Cat extends Animal{ // public function cry(){ // echo "abc"; // } // } // $cat1=new Cat(); // $cat1->cry(); |
// 当子类没有覆盖父类的方法则 $cat1->cry() 调用的是父类,当 子类覆盖了父类的方法,则调用自己的cry()
1.什么是第三方支付
所谓第三方支付,就是一些和各大银行签约、并具备一定实力和信誉保障的第三方独立机构提供的交易支持平台。在通过第三方支付平台的交易中,买方选购商品后,使用第三方平台提供的账户进行货款支付,由第三方通知卖家货款到达。
目前提供第三方支付的机构很多,常见的有支付宝、财付通、快钱、网银在线、易宝支付、云网等各大支付平台。网站如果需要实现第三方支付首先应该向第三方支付平台申请一个账号并签署协议,协议生效后第三方支付平台将为其开通在线支付功能,通过程序将接口集成到网站中。
为什么要使用第三方支付?因为第三方支付平台已经与各大银行进行签约,网站主只需要在此平台申请一个账号即可支持几乎所有的种类的银行卡信用卡的交易。
2.第三方支付原理
以上简要说明了支付过程,当然其中省略了一些步骤(比如购物车,订单等),我们重点来看支付流程。
2.1用户向商城网站发起确认订单的请求
2.2商城网站接收到请求保存订单数据到数据库或其他存储介质
2.3返回订单确认页面,页面上应该显示订单金额等信息
2.4用户确认支付,发起支付请求。注:支付请求是发送到支付网关(比如支付宝、网银在线)而不是发送到商城网站。
2.5显示支付页面
2.6用户填写认证信息(账号密码等)提交
2.7这里有两个步骤一个是扣款成功后页面跳转到支付结果页面(展示给用户),另一个是支付通知,这两步没有先后顺序可能同时执行,商城网站接收到支付通知后根据验证规则验证信息的有效性,并作出相应的更改操作(例:有效则更改订单为已付款状态,无效则记录非法请求信息)。
以支付宝为例:如果实现在网站中集成支付宝接口,首先要有一个支付宝账号,接下来向支付宝申请在线支付业务,签署协议。协议生效后有支付宝一方会给网站方一个合作伙伴ID,和安全校验码,有了这两样东西就可以按照支付宝接口文档开发支付宝接口了,在上图的几个步骤中只有4和7两个步骤在商城与支付网关之间有信息交互。在步骤4中指将数据发送到支付网关(支付宝),在步骤7中是的通知验证部分,验证网关请求网站某地址,网站按验证规则对信息进行验证记录并作出响应,我们几乎在开发任何支付接口时,重点是这两部分的开发,明白支付接口原理,开发支付接口就不难了。
3.支付宝接口开发
3.1接口简介与测试
支付宝目前提供了,担保交易、标准即时到帐、双功能等几种接口,只是在功能上有些差异,网站集成方式是一样的。以标准即时到帐接口为例,在与支付宝签署协议后,还需要几个步骤才能完成集成。
选择“我要自助集成”接下来会看到的链接,点击下载技术文档。
在下载后的文件中有标准支付宝交易服务接口、商家工具、接口集成指南等接文档,另外还有几种语言写的demo.我们可以根据接口文档按规则全新开发,也可以再demo基础上修改集成到网站,需要注意的是开发支付接口需要在公网(服务器必须可以通过外网访问)才可以完成整个调试过程,如果服务器在外网访问不到,则无法接收到支付通知。
看一下demo中每个文件的作用:
这里已经下载好了(见资源目录pay文件夹),为了便于调试增加修改了若干文件,并增加了一张数据表保存订单信息,我们修改一下配置文件完成一个测试过程。
alipay_config.php是基础信息配置文件,我们需要将在支付宝后台获取的PID与Key写入到配置文件中。
配置项:
其中方框内的数据是我们需要重点修改的。支付通知地址与返回地址的区别,前面已经提到,在步骤7中有两项:支付结果页面与支付通知信息,支付结果页面是用户支付完成后会自动跳转到这个地址这里是返回地址($return_url)。
支付通知地址同样是用户支付完成后,支付宝会请求该地址($notify_url),但是支付通知是支付宝服务器直接请求,不会被用户看到。这两个地址必须是以http开头的完整路径格式为了完成测试过程,这里已经将/pay/alipay/notify_url.php改写,将$notify_url设置为可访问到此文件的URL即可。这几项配置好后再根据数据库脚本(pay/orders.sql)创建一张数据表。并根据数据库的配置信息修改mysql_config.php.通过对支付宝提供的demo做简单修改就可以完成创建支付请求(步骤4)了,这里更改了支付首页等页面(见源码包pay目录)。我们先测试一下:
数据库中增加了一条“订单信息”.
如果点击“确认支付”按钮或者确认支付 链接将会跳转到支付宝页面,点击按钮时通过表单POST方式将信息提交到支付网关,由于支付请求数据无需让用户看到,这里都写在隐藏域中了。确认支付 链接是通过URL传参,因为支付宝接口允许以POST或者GET方式提交,所以两种方式都可以。把参数提交给支付网关后,页面跳转到到支付页面。我们看到如下图所示:
我们看到支付宝为我们提供了两种支付方式,一种是通过支付宝账户支付,另一种是通过银行卡支付。例如选择使用银行卡支付,填写邮箱或手机号跳转到如下页面:
我们开单支付宝几乎支持所有的银行卡支付,同时有信用卡和网点方式付款,选择对应的银行下一步按提示付款即可。付款完成后页面会返回到我们在配置文件中配置的$return_url地址,同时“订单状态”也会发生改变。
注:测试时如果没有在外网测试(即支付通知地址无法在外网访问)则支付通知无法被请求到,无法自动完成订单状态的修改。
3.2支付宝接口规范与代码分析
支付宝接口规范可参考/pay/doc/标准支付宝交易服务接口(专用于防钓鱼网站)。Pdf,里面已经有了比较详细的说明。
3.2.1如何创建支付请求
在前面的测试中我们点击了“确认支付”将信息将信息提交到了支付宝的支付网关,我们可以思考一下应该发送哪些参数给支付网关。关于请求参数列表可以参考标准支付宝交易服务接口(专用于防钓鱼网站)。Pdf中的3.2.2.需要注意的是并不是我们把这些参数原封不动的提交到支付宝就可以了,为了保证数据安全支付宝目前使用的是MD5签名防止数据篡改机制。
在提交数据前需要将需要提交的数据以一定规则(见接口文档)组装成字符串,加上安全校验码(Key)组成一个新字符串,通过MD5生成一个32字节的签名,我们提交支付请求时还需要把这个签名也提交过去。看一下表单源码
支付宝接收到参数后会进行验证请求参数的合法性,验证无误后将显示支付页面,否则提示错误。
3.2.2 如何验证支付通知
在用户支付完成后,支付宝会请求网站支付通知地址(这个地址应在创建支付请求时作为参数传递过去)。返回参数列表参见标准支付宝交易服务接口(专用于防钓鱼网站)。Pdf3.3.1.支付宝的返回数据中同样有一个签名串(采取和支付请求同样的签名方式),在支付通知文件中首先要对数据进行签名验证。除了验证签名,还需要将参数中的notify_id提交到支付宝的验证网关支付宝系统这个通知的真实性,通知验证。支付宝系统判断通知是否是自己发送,如果是以字符串格式返回 true,否则返回false,我们通过验证服务器返回的数据验证请求的真实性,如果都验证通过则可以进行更改订单数据、给用户发送邮件通知等操作。关于验证签名可以看一下通知文件中的源码。带demo中将参数中的notify_id提交到支付宝是通过POST方式提交并取得返回数据,代码片段:
这里重点就是fsockopen函数,在发送电子邮件时我们已经接触过,通过此函数打开套接字连接,类似于以前学过的fopen函数返回的是一个文件句柄,之后可以使用文件函数( fgets()、fgetss()、fputs()、fclose() feof()等)对其进行操作,代码中使用了fputs()(同fwrite())函数,写入数据来模拟表单以POST方式提交数据,最后通过fgets()函数获取返回的数据保存到数组中,最后进行验证,具体参照源码。
小编分享的这篇文章介绍了一个PHP实现的轻量级简单爬虫,不知道php怎么写爬虫的同学可以参考一下文中给出的实例代码。最近需要收集资料,在浏览器上用另存为的方式实在是很麻烦,而且不利于存储和检索。所以自己写了一个小爬虫,在网上爬东西,迄今为止,已经爬了近百 万张网页。现在正在想办法着手处理这些数据。
爬虫的结构:
爬虫的原理其实很简单,就是分析下载的页面,找出其中的连接,然后再下载这些链接,再分析再下载,周而复始。在数据存储方面,数据库是首选,便于检索,而 开发语言,只要支持正则表达式就可以了,数据库我选择了mysql,所以,开发脚本我选择了php。它支持perl兼容正则表达式,连接mysql很方 便,支持http下载,而且windows系统和linux系统都可以部署。
正则表达式:
正则表达式是处理文字的基本工具,要取出html中的链接和图片,使用的正则表达式如下。
"#<a[^>]+href=(['\"])(.+)\\1#isU" 处理链接
"#<img[^>]+src=(['\"])(.+)\\1#isU" 处理图片
其他问题:
写爬虫还需要注意的一个问题是,对于已经下载过的url,不能重复进行下载,而有些网页的链接会形成环路,所以需要处理这个问题,我的处理方法是计算已经 处理的url的MD5 值,并存入数据库,这样就可以检验是否已经下载过。当然还有更好的算法,有兴趣的话,可以在网上找一下。
相关协议:
爬虫也有自己的协议,有个robots.txt文件定义了那些是网站允许遍历的,但是由于我的时间有限,没有实现这个功能。
其他说明:
php支持类编程,我写的爬虫主要的类.
1.url处理web_site_info,主要用处理url,分析域名等。
2.数据库操作mysql_insert.php,处理和数据库相关的操作。
3.历史记录处理,记录已经处理的url。
4.爬虫类。
存在的问题和不足
这个爬虫在小数据量的情况下,运行良好,但是在大数据量的情况下,历史记录处理类的效率就不是很高,通过在数据库结构中,对相关字段进行了索引,速度有了 提高,但是需要不断得读取数据,可能和php本身的array实现有关系,如果一次加载10万条历史记录,速度非常慢。
不支持多线程,每次只能处理一个url。
php运行本身有内存使用量限制,有一次在抓取深度为20的页面的时候,内存用尽程序被杀。
下面的url是源码下载。
http://xiazai.jb51.net/201506/other/net_spider.rar
使用的时候,先在mysql中创建net_spider数据库,然后用db.sql创建相关表。再在config.php中设置mysql 的用户名口令。
最后
php -f spider.php 深度(数值) url
就可以开始工作。如
php -f spider.php 20 http://news.sina.com.cn
现在感觉下来,其实做个爬虫没那么复杂,难的是数据的存储和检索。我现在的数据库,最大一个数据表已经15G,正在想办处理这些数据,mysql进 行查询已经感觉有点力不从心了。这点上还真佩服google
代码如下 | 复制代码 |
<?php #加载页面 functioncurl_get($url){ $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_HEADER,1); $result=curl_exec($ch); $code=curl_getinfo($ch,CURLINFO_HTTP_CODE); if($code!='404'&&$result){ return$result; } curl_close($ch); } #获取页面url链接 functionget_page_urls($spider_page_result,$base_url){ $get_url_result=preg_match_all("/<[a|A].*?href=[\'\"]{0,1}([^>\'\"\]*).*?>/",$spider_page_result,$out); if($get_url_result){ return$out[1]; }else{ return; } } #相对路径转绝对路径 functionxdtojd($base_url,$url_list){ if(is_array($url_list)){ foreach($url_listas$url_item){ if(preg_match("/^(http:\/\/|https:\/\/|javascript:)/",$url_item)){ $result_url_list[]=$url_item; }else{ if(preg_match("/^\//",$url_item)){ $real_url=$base_url.$url_item; }else{ $real_url=$base_url."/".$url_item; } #$real_url='http://www.sumpay.cn/'.$url_item; $result_url_list[] =$real_url; } } return$result_url_list; }else{ return; } } #删除其他站点url functionother_site_url_del($jd_url_list,$url_base){ if(is_array($jd_url_list)){ foreach($jd_url_listas$all_url){ echo$all_url; if(strpos($all_url,$url_base)===0){ $all_url_list[]=$all_url; } } return$all_url_list; }else{ return; } } #删除相同URL functionurl_same_del($array_url){ if(is_array($array_url)){ $insert_url=array(); $pizza=file_get_contents("/tmp/url.txt"); if($pizza){ $pizza=explode("\r\n",$pizza); foreach($array_urlas$array_value_url){ if(!in_array($array_value_url,$pizza)){ $insert_url[]=$array_value_url; } } if($insert_url){ foreach($insert_urlas$key=>$insert_url_value){ #这里只做了参数相同去重处理 $update_insert_url=preg_replace('/=[^&]*/','=leesec',$insert_url_value); foreach($pizzaas$pizza_value){ $update_pizza_value=preg_replace('/=[^&]*/','=leesec',$pizza_value); if($update_insert_url==$update_pizza_value){ unset($insert_url[$key]); continue; } } } } }else{ $insert_url=array(); $insert_new_url=array(); $insert_url=$array_url; foreach($insert_urlas$insert_url_value){ $update_insert_url=preg_replace('/=[^&]*/','=leesec',$insert_url_value); $insert_new_url[]=$update_insert_url; } $insert_new_url=array_unique($insert_new_url); foreach($insert_new_urlas$key=>$insert_new_url_val){ $insert_url_bf[]=$insert_url[$key]; } $insert_url=$insert_url_bf; } return$insert_url; }else{ return; } }
$current_url=$argv[1]; $fp_puts=fopen("/tmp/url.txt","ab");//记录url列表 $fp_gets=fopen("/tmp/url.txt","r");//保存url列表 $url_base_url=parse_url($current_url); if($url_base_url['scheme']==""){ $url_base="http://".$url_base_url['host']; }else{ $url_base=$url_base_url['scheme']."://".$url_base_url['host']; } do{ $spider_page_result=curl_get($current_url); #var_dump($spider_page_result); $url_list=get_page_urls($spider_page_result,$url_base); #var_dump($url_list); if(!$url_list){ continue; } $jd_url_list=xdtojd($url_base,$url_list); #var_dump($jd_url_list); $result_url_arr=other_site_url_del($jd_url_list,$url_base); var_dump($result_url_arr); $result_url_arr=url_same_del($result_url_arr); #var_dump($result_url_arr); if(is_array($result_url_arr)){ $result_url_arr=array_unique($result_url_arr); foreach($result_url_arras$new_url) { fputs($fp_puts,$new_url."\r\n"); } } }while($current_url=fgets($fp_gets,1024));//不断获得url preg_match_all("/<a[^>]+href=[\"']([^\"']+)[\"'][^>]+>/",$spider_page_result,$out); #echoa href #var_dump($out[1]); ?> |
index.php
代码如下 | 复制代码 |
<html> <head> <title>First PHP</title> </head> <body> <form name="form_a" method="post", action="fa.php"> 用户名: <input name="user" type="text" value="" size="12" maxlength="1000"> <br/> 密码: <input name="pwd" type="password" value="" size="12" maxlength="20"> <br/> 性别: <input name="sex" type="radio" value="男" checked>男 <input name="sex" type="radio" value="女">女 <br/><br/> 购买书籍:<br/> <?php $books = array("Linux设计", "C++软件设计", "PHP网页开发"); foreach ($books as $i=>$book) { echo "<input name=\"books\" type=\"checkbox\" value=$i>$book\n<br>\n"; } ?> <br/> |
选择课程:
代码如下 | 复制代码 |
<select name="class" id="class"> <?php $classes = array("C++程序设计", "C程序设计", "MFC程序设计", "Qt编程", "网络编程", "SQL数据库设计"); foreach ($classes as $key=>$value) { echo '<option value="' .$key.'">' . $value . '</option>\n'; } ?> </select> <br/> <input name="submit" type="submit" value="提交"> </form> </body> </html> |
fa.php
代码如下 | 复制代码 |
<?php #echo 'user: ' . $_POST["user"]; print_r($_POST); ?> |
相关文章
php 中file_get_contents超时问题的解决方法
file_get_contents超时我知道最多的原因就是你机器访问远程机器过慢,导致php脚本超时了,但也有其它很多原因,下面我来总结file_get_contents超时问题的解决方法总结。...2016-11-25- 相信很多站长都遇到过这样一个问题,访问页面时出现408错误,下面一聚教程网将为大家介绍408错误出现的原因以及408错误的解决办法。 HTTP 408错误出现原因: HTT...2017-01-22
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
- ps软件是现在非常受大家喜欢的一款软件,有着非常不错的使用功能。这次文章就给大家介绍下ps把文字背景变透明的操作方法,喜欢的一起来看看。 1、使用Photoshop软件...2017-07-06
intellij idea快速查看当前类中的所有方法(推荐)
这篇文章主要介绍了intellij idea快速查看当前类中的所有方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-09-02- 1.在没有设置默认值的情况下: 复制代码 代码如下:SELECT userinfo.id, user_name, role, adm_regionid, region_name , create_timeFROM userinfoLEFT JOIN region ON userinfo.adm_regionid = region.id 结果:...2014-05-31
js导出table数据到excel即导出为EXCEL文档的方法
复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta ht...2013-10-13- 本文涉及的主题虽然很基础,在许多人看来属于小伎俩,但在JavaScript基础知识中属于一个综合性的话题。这里会涉及到对象属性的封装、原型、构造函数、闭包以及立即执行表达式等知识。公有方法 公有方法就是能被外部访问...2015-11-08
- 批量更新mysql更新语句很简单,更新一条数据的某个字段,一般这样写:复制代码 代码如下:UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value';如果更新同一字段为同一个值,mysql也很简单,修改下where即...2013-10-04
- 单个字符分割 string s="abcdeabcdeabcde"; string[] sArray=s.Split('c'); foreach(string i in sArray) Console.WriteLine(i.ToString()); 输出下面的结果: ab de...2020-06-25
- ps软件是一款非常不错的图片处理软件,有着非常不错的使用效果。这次文章要给大家介绍的是ps怎么制作倒影,一起来看看设计倒影的方法。 用ps怎么做倒影最终效果̳...2017-07-06
- 最近想自学PHP ,做了个验证码,但不知道怎么搞的,总出现一个如下图的小红叉,但验证码就是显示不出来,原因如下 未修改之前,出现如下错误; (1)修改步骤如下,原因如下,原因是apache权限没开, (2)点击打开php.int., 搜索extension=ph...2013-10-04
安卓手机wifi打不开修复教程,安卓手机wifi打不开解决方法
手机wifi打不开?让小编来告诉你如何解决。还不知道的朋友快来看看。 手机wifi是现在生活中最常用的手机功能,但是遇到手机wifi打不开的情况该怎么办呢?如果手机wifi...2016-12-21连接MySql速度慢的解决方法(skip-name-resolve)
最近在Linux服务器上安装MySql5后,本地使用客户端连MySql速度超慢,本地程序连接也超慢。 解决方法:在配置文件my.cnf的[mysqld]下加入skip-name-resolve。原因是默认安装的MySql开启了DNS的反向解析。如果禁用的话就不能...2015-10-21- javascript控制页面控件隐藏显示的两种方法,方法的不同之处在于控件隐藏后是否还在页面上占位 方法一: 复制代码 代码如下: document.all["panelsms"].style.visibility="hidden"; document.all["panelsms"].style.visi...2013-10-13
- 本篇文章是对C#方法进行了详细的总结与介绍,需要的朋友参考下...2020-06-25
- 步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
- EXCEL数据上传到SQL SERVER中的方法需要注意到三点!注意点一:要把EXCEL数据上传到SQL SERVER中必须提前把EXCEL传到服务器上.做法: 在ASP.NET环境中,添加一个FileUpload上传控件后台代码的E.X: 复制代码 代码如下: if...2013-09-23
- mysql锁定单个表的方法 复制代码 代码如下:mysql>lock table userstat read; mysql>unlock tables; 页级的典型代表引擎为BDB。 表级的典型代表引擎为MyISAM,MEMORY以及很久以前的ISAM。 行级的典型代表引擎为INN...2014-05-31