php抽象类与接口的区别详解
区别:
1、对接口的使用是通过关键字implements。对抽象类的使用是通过关键字extends。当然接口也可以通过关键字extends继承。
2、接口中不可以声明成员变量(包括类静态变量),但是可以声明类常量。抽象类中可以声明各种类型成员变量,实现数据的封装。(另JAVA接口中的成员变量都要声明为public static final类型)
3、接口没有构造函数,抽象类可以有构造函数。
4、接口中的方法默认都是public类型的,而抽象类中的方法可以使用private,protected,public来修饰。
5、一个类可以同时实现多个接口,但一个类只能继承于一个抽象类。
抽象类还是接口。
如果要创建一个模型,这个模型将由一些紧密相关的对象采用,就可以使用抽象类。如果要创建将由一些不相关对象采用的功能,就使用接口。
如果必须从多个来源继承行为,就使用接口。
如果知道所有类都会共享一个公共的行为实现,就使用抽象类,并在其中实现该行为
例子
<?php
abstract class Father {
function meth1() {
echo "meth1...<br>";
}
abstract function meth2();
public $var1="var1";
public static $var2="var2";
const Var3="Var3";
}
class Son extends Father {
function meth2() {
echo "meth2 of Son...<br>";
}
}
$s=new Son();
echo $s->var1."<br>";
echo Father::$var2."<br>";
echo Father::Var3."<br>";
Interface IFather {
//public $iVar1="iVar1"; 此处接口定义中不能包含成员变量
//public static $iVar2="iVar2"; 此处接口定义中不能包含静态变量
const iVar3="iVar3";
function iMeth1();
}
Class ISon implements IFather {
function iMeth1() {
echo "iMeth1...<br>";
}
}
$is=new ISon();
echo IFather::iVar3;
?>
如果更详细一点我们可以对每一个都介绍一下
抽象类:是基于类来说,其本身就是类,只是一种特殊的类,不能直接实例,可以在类里定义方法,属性。类似于模版,规范后让子类实现详细功能。
接口:主要基于方法的规范,有点像抽象类里的抽象方法,只是其相对于抽象方法来说,更加独立。可让某个类通过组合多个方法来形成新的类。
抽象类与接口的相同点:
1、都是用于声明某一种事物,规范名称、参数,形成模块,未有详细的实现细节。
2、都是通过类来实现相关的细节工作
3、语法上,抽象类的抽象方法与接口一样,不能有方法体,即{}符号
4、都可以用继承,接口可以继承接口形成新的接口,抽象类可以继承抽象类从而形成新的抽象类
抽象类与接口的不同点:
1、抽象类可以有属性、普通方法、抽象方法,但接口不能有属性、普通方法、可以有常量
2、抽象类内未必有抽象方法,但接口内一定会有“抽象”方法
3、语法上有不同
4、抽象类用abstract关键字在类前声明,且有class声明为类,接口是用interface来声明,但不能用class来声明,因为接口不是类。
5、抽象类的抽象方法一定要用abstract来声明,而接口则不需要
6、抽象类是用extends关键字让子类继承父类后,在子类实现详细的抽象方法。而接口则是用implements让普通类在类里实现接口的详细方法,且接口可以一次性实现多个方法,用逗号分开各个接口就可
各自的特点:
抽象类内未必有抽象方法,但有抽象方法的类,则必是抽象类
抽象类内,即便全是具体方法,也不能够实例化,只要新建类来继承后,实例继承类才可以
接口可以让一个类一次性实现多个不同的方法
接口本身就是抽象的,但注意不是抽象类,因为接口不是类,只是其方法是抽象的。所以,其也是抽象的
应用与结合:
以下的代码是基于自己的思考,未在实际开发中应用,只是这种写法有点奇特。让抽象与接口结合起来。
一、抽象类与接口的结合
<?php
/*
写此程序源于自己的猜测,想在抽象类里实现某一接口。
*/
interface work{
public function say();
}
abstract class a implements work{
public function showlove(){
echo 'love you<br />';
}
}
class b extends a{
public function say(){
echo 'hello, i m in b';
}
}
$k=new b();
$k->say();
/*
以上程序能正常执行
普通类implements接口后,就变成了抽象类了,这就好像是直接给抽象类增加了一个抽象方法。
*/
二、接口与继承的结合
父类是普通类,子类继承后,同时在子类里实现接口。
疑问:这样的做法是否有意义,在实际开发中是否有这样的应用?
<?php
interface kk{
public function say();
}
class a {
public function show(){
echo '我是父类<br />';
}
}
class b extends a implements kk{
public function say(){
echo '我是继承A类,同时实现say接口的<br />';
}
}
$b=new b();
$b->show();//我是父类
$b->say();//我是继承A类,同时实现say接口的
下面是一个php数据库备份的源代码,大家也可以根据自己的需求进行修改。
<?php
// 备份数据库
$host = "localhost";
$user = "root"; //数据库账号
$password = ""; //数据库密码
$dbname = "mysql"; //数据库名称
// 这里的账号、密码、名称都是从页面传过来的
if (!mysql_connect($host, $user, $password)) // 连接mysql数据库
{
echo '数据库连接失败,请核对后再试';
exit;
}
if (!mysql_select_db($dbname)) // 是否存在该数据库
{
echo '不存在数据库:' . $dbname . ',请核对后再试';
exit;
}
mysql_query("set names 'utf8'");
$mysql = "set charset utf8;\r\n";
$q1 = mysql_query("show tables");
while ($t = mysql_fetch_array($q1))
{
$table = $t[0];
$q2 = mysql_query("show create table `$table`");
$sql = mysql_fetch_array($q2);
$mysql .= $sql['Create Table'] . ";\r\n";
$q3 = mysql_query("select * from `$table`");
while ($data = mysql_fetch_assoc($q3))
{
$keys = array_keys($data);
$keys = array_map('addslashes', $keys);
$keys = join('`,`', $keys);
$keys = "`" . $keys . "`";
$vals = array_values($data);
$vals = array_map('addslashes', $vals);
$vals = join("','", $vals);
$vals = "'" . $vals . "'";
$mysql .= "insert into `$table`($keys) values($vals);\r\n";
}
}
$filename = $dbname . date('Ymjgi') . ".sql"; //存放路径,默认存放到项目最外层
$fp = fopen($filename, 'w');
fputs($fp, $mysql);
fclose($fp);
echo "数据备份成功";
?>
如果使用的是thinkphp可以使用下面代码来备份mysql数据库
<?php
// www.111cn.net
class BaksqlAction extends CommonAction {
public $config = ''; //相关配置
public $model = ''; //实例化一个model
public $content; //内容
public $dbName = ''; //数据库名
public $dir_sep = '/'; //路径符号
//初始化数据
function _initialize() {
parent::_initialize();
header("Content-type: text/html;charset=utf-8");
set_time_limit(0); //不超时
ini_set('memory_limit','500M');
$this->config = array(
'path' => C('DB_BACKUP'), //备份文件存在哪里
'isCompress' => 0, //是否开启gzip压缩 【未测试】
'isDownload' => 0 //备份完成后是否下载文件 【未测试】
);
$this->dbName = C('DB_NAME'); //当前数据库名称
$this->model = new Model();
//$sql = 'set interactive_timeout=24*3600'; //空闲多少秒后 断开链接
//$this->model>execute($sql);
}
/* -
* +------------------------------------------------------------------------
* * @ 已备份数据列表
* +------------------------------------------------------------------------
*/
function index() {
$path = $this->config['path'];
$fileArr = $this->MyScandir($path);
foreach ($fileArr as $key => $value) {
if ($key > 1) {
//获取文件创建时间
$fileTime = date('Y-m-d H:i:s', filemtime($path . '/' . $value));
$fileSize = filesize($path . '/' . $value) / 1024;
//获取文件大小
$fileSize = $fileSize < 1024 ? number_format($fileSize, 2) . ' KB' :
number_format($fileSize / 1024, 2) . ' MB';
//构建列表数组
$list[] = array(
'name' => $value,
'time' => $fileTime,
'size' => $fileSize
);
}
}
$this->assign('list', $list);
$this->display();
}
/* -
* +------------------------------------------------------------------------
* * @ 获取数据表
* +------------------------------------------------------------------------
*/
function tablist() {
$list = $this->model->query("SHOW TABLE STATUS FROM {$this->dbName}"); //得到表的信息
//echo $Backup->getLastSql();
$this->assign('list', $list);
$this->display();
}
/* -
* +------------------------------------------------------------------------
* * @ 备份整个数据库
* +------------------------------------------------------------------------
*/
function backall() {
$tables = $this->getTables();
if ($this->backup($tables)) {
$this->success('数据库备份成功!', '/public/ok');
} else {
$this->error('数据库备份失败!');
}
}
/* -
* +------------------------------------------------------------------------
* * @ 按表备份,可批量
* +------------------------------------------------------------------------
*/
function backtables() {
$tab = $_REQUEST['tab'];
if (is_array($tab))
$tables = $tab;
else
$tables[] = $tab;
if ($this->backup($tables)) {
if (is_array($tab))
$this->success('数据库备份成功!');
else
$this->success('数据库备份成功!', '/public/ok');
} else {
$this->error('数据库备份失败!');
}
}
//还原数据库
function recover() {
if ($this->recover_file($_GET['file'])) {
$this->success('数据还原成功!', '/public/ok');
} else {
$this->error('数据还原失败!');
}
}
//删除数据备份
function deletebak() {
if (unlink($this->config['path'] . $this->dir_sep . $_GET['file'])) {
$this->success('删除备份成功!', '/public/ok');
} else {
$this->error('删除备份失败!');
}
}
/* -
* +------------------------------------------------------------------------
* * @ 下载备份文件
* +------------------------------------------------------------------------
*/
function downloadBak() {
$file_name = $_GET['file'];
$file_dir = $this->config['path'];
if (!file_exists($file_dir . "/" . $file_name)) { //检查文件是否存在
return false;
exit;
} else {
$file = fopen($file_dir . "/" . $file_name, "r"); // 打开文件
// 输入文件标签
header('Content-Encoding: none');
header("Content-type: application/octet-stream");
header("Accept-Ranges: bytes");
header("Accept-Length: " . filesize($file_dir . "/" . $file_name));
header('Content-Transfer-Encoding: binary');
header("Content-Disposition: attachment; filename=" . $file_name); //以真实文件名提供给浏览器下载
header('Pragma: no-cache');
header('Expires: 0');
//输出文件内容
echo fread($file, filesize($file_dir . "/" . $file_name));
fclose($file);
exit;
}
}
/* -
* +------------------------------------------------------------------------
* * @ 获取 目录下文件数组
* +------------------------------------------------------------------------
* * @ $FilePath 目录路径
* * @ $Order 排序
* +------------------------------------------------------------------------
* * @ 获取指定目录下的文件列表,返回数组
* +------------------------------------------------------------------------
*/
private function MyScandir($FilePath = './', $Order = 0) {
$FilePath = opendir($FilePath);
while ($filename = readdir($FilePath)) {
$fileArr[] = $filename;
}
$Order == 0 ? sort($fileArr) : rsort($fileArr);
return $fileArr;
}
/* * ******************************************************************************************** */
/* -
* +------------------------------------------------------------------------
* * @ 读取备份文件
* +------------------------------------------------------------------------
* * @ $fileName 文件名
* +------------------------------------------------------------------------
*/
private function getFile($fileName) {
$this->content = '';
$fileName = $this->trimPath($this->config['path'] . $this->dir_sep . $fileName);
if (is_file($fileName)) {
$ext = strrchr($fileName, '.');
if ($ext == '.sql') {
$this->content = file_get_contents($fileName);
} elseif ($ext == '.gz') {
$this->content = implode('', gzfile($fileName));
} else {
$this->error('无法识别的文件格式!');
}
} else {
$this->error('文件不存在!');
}
}
/* -
* +------------------------------------------------------------------------
* * @ 把数据写入磁盘
* +------------------------------------------------------------------------
*/
private function setFile() {
$recognize = '';
$recognize = $this->dbName;
$fileName = $this->trimPath($this->config['path'] . $this->dir_sep . $recognize . '_' . date('YmdHis') . '_' . mt_rand(100000000, 999999999) . '.sql');
$path = $this->setPath($fileName);
if ($path !== true) {
$this->error("无法创建备份目录目录 '$path'");
}
if ($this->config['isCompress'] == 0) {
if (!file_put_contents($fileName, $this->content, LOCK_EX)) {
$this->error('写入文件失败,请检查磁盘空间或者权限!');
}
} else {
if (function_exists('gzwrite')) {
$fileName .= '.gz';
if ($gz = gzopen($fileName, 'wb')) {
gzwrite($gz, $this->content);
gzclose($gz);
} else {
$this->error('写入文件失败,请检查磁盘空间或者权限!');
}
} else {
$this->error('没有开启gzip扩展!');
}
}
if ($this->config['isDownload']) {
$this->downloadFile($fileName);
}
}
private function trimPath($path) {
return str_replace(array('/', '\\', '//', '\\\\'), $this->dir_sep, $path);
}
private function setPath($fileName) {
$dirs = explode($this->dir_sep, dirname($fileName));
$tmp = '';
foreach ($dirs as $dir) {
$tmp .= $dir . $this->dir_sep;
if (!file_exists($tmp) && !@mkdir($tmp, 0777))
return $tmp;
}
return true;
}
//未测试
private function downloadFile($fileName) {
ob_end_clean();
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($fileName));
header('Content-Disposition: attachment; filename=' . basename($fileName));
readfile($fileName);
}
/* -
* +------------------------------------------------------------------------
* * @ 给字符串添加 ` `
* +------------------------------------------------------------------------
* * @ $str 字符串
* +------------------------------------------------------------------------
* * @ 返回 `$str`
* +------------------------------------------------------------------------
*/
private function backquote($str) {
return "`{$str}`";
}
/* -
* +------------------------------------------------------------------------
* * @ 获取数据库的所有表
* +------------------------------------------------------------------------
* * @ $dbName 数据库名称
* +------------------------------------------------------------------------
*/
private function getTables($dbName = '') {
if (!empty($dbName)) {
$sql = 'SHOW TABLES FROM ' . $dbName;
} else {
$sql = 'SHOW TABLES ';
}
$result = $this->model->query($sql);
$info = array();
foreach ($result as $key => $val) {
$info[$key] = current($val);
}
return $info;
}
/* -
* +------------------------------------------------------------------------
* * @ 把传过来的数据 按指定长度分割成数组
* +------------------------------------------------------------------------
* * @ $array 要分割的数据
* * @ $byte 要分割的长度
* +------------------------------------------------------------------------
* * @ 把数组按指定长度分割,并返回分割后的数组
* +------------------------------------------------------------------------
*/
private function chunkArrayByByte($array, $byte = 5120) {
$i = 0;
$sum = 0;
$return = array();
foreach ($array as $v) {
$sum += strlen($v);
if ($sum < $byte) {
$return[$i][] = $v;
} elseif ($sum == $byte) {
$return[++$i][] = $v;
$sum = 0;
} else {
$return[++$i][] = $v;
$i++;
$sum = 0;
}
}
return $return;
}
/* -
* +------------------------------------------------------------------------
* * @ 备份数据 { 备份每张表、视图及数据 }
* +------------------------------------------------------------------------
* * @ $tables 需要备份的表数组
* +------------------------------------------------------------------------
*/
private function backup($tables) {
if (empty($tables))
$this->error('没有需要备份的数据表!');
$this->content = '/* This file is created by MySQLReback ' . date('Y-m-d H:i:s') . ' */';
foreach ($tables as $i => $table) {
$table = $this->backquote($table); //为表名增加 ``
$tableRs = $this->model->query("SHOW CREATE TABLE {$table}"); //获取当前表的创建语句
if (!empty($tableRs[0]["Create View"])) {
$this->content .= "\r\n /* 创建视图结构 {$table} */";
$this->content .= "\r\n DROP VIEW IF EXISTS {$table};/* MySQLReback Separation */ " . $tableRs[0]["Create View"] . ";/* MySQLReback Separation */";
}
if (!empty($tableRs[0]["Create Table"])) {
$this->content .= "\r\n /* 创建表结构 {$table} */";
$this->content .= "\r\n DROP TABLE IF EXISTS {$table};/* MySQLReback Separation */ " . $tableRs[0]["Create Table"] . ";/* MySQLReback Separation */";
$tableDateRow = $this->model->query("SELECT * FROM {$table}");
$valuesArr = array();
$values = '';
if (false != $tableDateRow) {
foreach ($tableDateRow as &$y) {
foreach ($y as &$v) {
if ($v=='') //纠正empty 为0的时候 返回tree
$v = 'null'; //为空设为null
else
$v = "'" . mysql_escape_string($v) . "'"; //非空 加转意符
}
$valuesArr[] = '(' . implode(',', $y) . ')';
}
}
$temp = $this->chunkArrayByByte($valuesArr);
if (is_array($temp)) {
foreach ($temp as $v) {
$values = implode(',', $v) . ';/* MySQLReback Separation */';
if ($values != ';/* MySQLReback Separation */') {
$this->content .= "\r\n /* 插入数据 {$table} */";
$this->content .= "\r\n INSERT INTO {$table} VALUES {$values}";
}
}
}
// dump($this->content);
// exit;
}
}
if (!empty($this->content)) {
$this->setFile();
}
return true;
}
/* -
* +------------------------------------------------------------------------
* * @ 还原数据
* +------------------------------------------------------------------------
* * @ $fileName 文件名
* +------------------------------------------------------------------------
*/
private function recover_file($fileName) {
$this->getFile($fileName);
if (!empty($this->content)) {
$content = explode(';/* MySQLReback Separation */', $this->content);
foreach ($content as $i => $sql) {
$sql = trim($sql);
if (!empty($sql)) {
$mes = $this->model->execute($sql);
if (false === $mes) { //如果 null 写入失败,换成 ''
$table_change = array('null' => '\'\'');
$sql = strtr($sql, $table_change);
$mes = $this->model->execute($sql);
}
if (false === $mes) { //如果遇到错误、记录错误
$log_text = '以下代码还原遇到问题:';
$log_text.="\r\n $sql";
set_log($log_text);
}
}
}
} else {
$this->error('无法读取备份文件!');
}
return true;
}
}
?>
PHP7已经发布了, 作为PHP10年来最大的版本升级, 最大的性能升级, PHP7在多放的测试中都表现出很明显的性能提升, 然而, 为了让它能发挥出最大的性能, 我还是有几件事想提醒下.
PHP7 VS PHP5.6
1. Opcache
记得启用Zend Opcache, 因为PHP7即使不启用Opcache速度也比PHP-5.6启用了Opcache快, 所以之前测试时期就发生了有人一直没有启用Opcache的事情. 启用Opcache非常简单, 在php.ini配置文件中加入:
zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1"
2. 使用新的编译器
使用新一点的编译器, 推荐GCC 4.8以上, 因为只有GCC 4.8以上PHP才会开启Global Register for opline and execute_data支持, 这个会带来5%左右的性能提升(Wordpres的QPS角度衡量)
其实GCC 4.8以前的版本也支持, 但是我们发现它支持的有Bug, 所以必须是4.8以上的版本才会开启这个特性.
3. HugePage
我之前的文章也介绍过: 让你的PHP7更快之Hugepage , 首先在系统中开启HugePages, 然后开启Opcache的huge_code_pages.
以我的CentOS 6.5为例, 通过:
$sudo sysctl vm.nr_hugepages=512
分配512个预留的大页内存:
$ cat /proc/meminfo | grep Huge
AnonHugePages: 106496 kB
HugePages_Total: 512
HugePages_Free: 504
HugePages_Rsvd: 27
HugePages_Surp: 0
Hugepagesize: 2048 kB
然后在php.ini中加入:
opcache.huge_code_pages=1
这样一来, PHP会把自身的text段, 以及内存分配中的huge都采用大内存页来保存, 减少TLB miss, 从而提高性能.
4. Opcache file cache
开启Opcache File Cache(实验性), 通过开启这个, 我们可以让Opcache把opcode缓存缓存到外部文件中, 对于一些脚本, 会有很明显的性能提升.
在php.ini中加入:
opcache.file_cache=/tmp
这样PHP就会在/tmp目录下Cache一些Opcode的二进制导出文件, 可以跨PHP生命周期存在.
5. PGO
我之前的文章: 让你的PHP7更快(GCC PGO) 也介绍过, 如果你的PHP是专门为一个项目服务, 比如只是为你的Wordpress, 或者drupal, 或者其他什么, 那么你就可以尝试通过PGO, 来提升PHP, 专门为你的这个项目提高性能.
具体的, 以wordpress 4.1为优化场景.. 首先在编译PHP的时候首先:
$ make prof-gen
然后用你的项目训练PHP, 比如对于Wordpress:
$ sapi/cgi/php-cgi -T 100 /home/huixinchen/local/www/htdocs/wordpress/index.php >/dev/null
也就是让php-cgi跑100遍wordpress的首页, 从而生成一些在这个过程中的profile信息.
最后:
$ make prof-clean
$ make prof-use && make install
这个时候你编译得到的PHP7就是为你的项目量身打造的最高性能的编译版本.
加密解密
//Hex(Hex(Md5((原文+密钥).getBytes(“utf-8”))).getBytes(“utf-8”))
function String2Hex($string){
$hex='';
for ($i=0; $i < strlen($string); $i++){
$hex .= dechex(ord($string[$i]));
}
return $hex;
}
function Hex2String($hex){
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2){
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
// example:
$hex = String2Hex("test sentence...");
$data = array(
'appId' => 'SHAN-GUO-CHI-BI',
'data' =>'{"appId":"SHAN-GUO-CHI-BI","cardNo":"6006012000000001"}',
'sig'=>'4331443139334331313645464642444544364334343742374236364335454243',
);
$key = '111111111111111111111111';
$data['sig'] = String2Hex(strtoupper(md5($data['data'] . $key)));
例子
PHP 转换输出字符串为 Hex Oct
通过下面代码,可以把PHP输出的字符串换行为16进制和8进制。
<?php
$str = "http://www.111cn.net";
$lixiphp = ”;
for($i = 0; $i < strlen($str); $i++) {
if ($i % 2 == 0) {
$lixiphp .= ‘\x’.base_convert(ord($str[$i]), 10, 16);
}
else {
$lixiphp .= ‘\\’.base_convert(ord($str[$i]), 10, 8);
}
}
echo $lixiphp;
?>
通过上述代码,把字符串 "http://www.111cn.net" 转换为"\x68\164\x74\160\x3a\57\x2f\142\x6c\157\x67\56\x6c\151\x78\151\x70\150\x70\56\x63\157\x6d"
PHP实现来基数位字符串转换十六进制,偶数位字符串转换为八进制。
下图是ASCII码表,可以简单的核对10进制、8进制和16进制与127常用字符的关系。
相关文章
mysql_connect与mysql_pconnect的区别详解
在mysql中我们会看到有两种常用的数据库连接模式,一种是长久连接,另一各是页面访问完之后就断了连接,下面我来分别介绍mysql_connect与mysql_pconnect的区别,有需要了解...2016-11-25- 这篇文章主要介绍了源码分析系列之json_encode()如何转化一个对象,对json_encode()感兴趣的同学,可以参考下...2021-04-22
- PHP去除html、css样式、js格式的方法很多,但发现,它们基本都有一个弊端:空格往往清除不了 经过不断的研究,最终找到了一个理想的去除html包括空格css样式、js 的PHP函数。...2013-08-02
- 这篇文章主要介绍了c# 三种方法调用WebService接口的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-07
- index.php怎么打开?初学者可能不知道如何打开index.php,不会的同学可以参考一下本篇教程 打开编辑:右键->打开方式->经文本方式打开打开运行:首先你要有个支持运行PH...2017-07-06
- 这篇文章主要介绍了vue接口请求加密实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-12
- 这篇文章主要介绍了C#中out与ref的区别实例解析,对C#初学者有不错的学习借鉴价值,需要的朋友可以参考下...2020-06-25
PHP中func_get_args(),func_get_arg(),func_num_args()的区别
复制代码 代码如下:<?php function jb51(){ print_r(func_get_args()); echo "<br>"; echo func_get_arg(1); echo "<br>"; echo func_num_args(); } jb51("www","j...2013-10-04谈谈Jquery中的children find 的区别有哪些
精华:find方法能找子孙,children方法只能找儿子一、Jquery中children 语法.children(selector) 说明expr是表达式,可选参数,所有选择器中的表达式都可以用在这,比如按标签名"div",按类名".class",按序号":first"等等,如果表...2015-10-21- 这篇文章主要介绍了PHP编程 SSO详细介绍及简单实例的相关资料,这里介绍了三种模式跨子域单点登陆、完全跨单点域登陆、站群共享身份认证,需要的朋友可以参考下...2017-01-25
- 这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19
- 这篇文章主要介绍了PHP实现创建以太坊钱包转账等功能,对以太坊感兴趣的同学,可以参考下...2021-04-20
- 在PS中像素大小、文档大小有什么区别呢,这个估计很多初学者不清楚,下面我来给大家讲解一下,希望对你有帮助。 1、像素大小 通常用于显示屏显示的图片大小的调整。菜...2016-09-14
- 这篇文章主要介绍了C# Rx的主要接口深入理解的相关资料,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了C#简单了解接口(Interface)使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-12-08
- 这篇文章主要为大家详细介绍了php微信公众账号开发之五个坑,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-10-02
- 这篇文章主要介绍了Feign接口方法返回值设置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-08
- 在日常开发中,总会接触到各种接口,前后端数据传输接口,第三方业务平台接口,下面这篇文章主要给大家介绍了关于如何设计一个安全的API接口的相关资料,需要的朋友可以参考下...2021-08-12
- 这篇文章主要介绍了PHP如何通过date() 函数格式化显示时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-13
- php怎么写api接口?本文介绍了php写api接口的实例代码,有兴趣的同学可以参考一下。 http://localhost/openUser.php?act=get_user_list&type=json在这里openUser.php...2017-07-06