适用平台:window/Linux
依赖项目:EaglePHP框架
包含微信5.0 API基础接口、自定义菜单、高级接口,具体如下:
1、接收用户消息。
2、向用户回复消息。
3、接受事件推送。
4、会话界面自定义菜单。
5、语音识别。
6、客服接口。
7、OAuth2.0网页授权。
8、生成带参数二维码。
9、获取用户地理位置。
10、获取用户基本信息。
11、获取关注者列表。
12、用户分组。
/**
* 微信公众平台API
*/
class WeixinChat
{
private $token;
private $appid;
private $appsecret;
private $access_token;
// 接收的数据
private $_receive = array();
private $_reply = '';
// 接口错误码
private $errCode = '';
// 接口错误信息
private $errMsg = '';
// 微信oauth登陆获取code
const CONNECT_OAUTH_AUTHORIZE_URL = 'https://open.weixin.qq.com/connect/oauth2/authorize?';
// 微信oauth登陆通过code换取网页授权access_token
const SNS_OAUTH_ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/sns/oauth2/access_token?';
// 微信oauth登陆刷新access_token(如果需要)
const SNS_OAUTH_REFRESH_TOKEN_URL = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?';
// 通过ticket换取二维码
const SHOW_QRCODE_URL = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?';
// 微信oauth登陆拉取用户信息(需scope为 snsapi_userinfo)
const SNS_USERINFO_URL = 'https://api.weixin.qq.com/sns/userinfo?';
// 请求api前缀
const API_URL_PREFIX = 'https://api.weixin.qq.com/cgi-bin';
// 自定义菜单创建
const MENU_CREATE_URL = '/menu/create?';
// 自定义菜单查询
const MENU_GET_URL = '/menu/get?';
// 自定义菜单删除
const MENU_DELETE_URL = '/menu/delete?';
// 获取 access_token
const AUTH_URL = '/token?grant_type=client_credential&';
// 获取用户基本信息
const USER_INFO_URL = '/user/info?';
// 获取关注者列表
const USER_GET_URL = '/user/get?';
// 查询分组
const GROUPS_GET_URL = '/groups/get?';
// 创建分组
const GROUPS_CREATE_URL = '/groups/create?';
// 修改分组名
const GROUPS_UPDATE_URL = '/groups/update?';
// 移动用户分组
const GROUPS_MEMBERS_UPDATE_URL = '/groups/members/update?';
// 发送客服消息
const MESSAGE_CUSTOM_SEND_URL = '/message/custom/send?';
// 创建二维码ticket
const QRCODE_CREATE_URL = '/qrcode/create?';
/**
* 初始化配置数据
* @param array $options
*/
public function __construct($options)
{
$this->token = isset($options['token']) ? $options['token'] : '';
$this->appid = isset($options['appid']) ? $options['appid'] : '';
$this->appsecret = isset($options['appsecret']) ? $options['appsecret'] : '';
}
/**
* 获取发来的消息
* 当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。
*/
public function getRev()
{
$postStr = file_get_contents('php://input');
if($postStr)
{
$this->_receive = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
//Log::info(var_export($this->_receive, true));
}
return $this;
}
/**
* 获取微信服务器发来的消息
*/
public function getRevData()
{
return $this->_receive;
}
/**
* 获取接收者
*/
public function getRevTo()
{
return isset($this->_receive['ToUserName']) ? $this->_receive['ToUserName'] : false;
}
/**
* 获取消息发送者(一个OpenID)
*/
public function getRevFrom()
{
return isset($this->_receive['FromUserName']) ? $this->_receive['FromUserName'] : false;
}
/**
* 获取接收消息创建时间 (整型)
*/
public function getRevCTime()
{
return isset($this->_receive['CreateTime']) ? $this->_receive['CreateTime'] : false;
}
/**
* 获取接收消息类型(text、image、voice、video、location、link、event)
*/
public function getRevType()
{
return isset($this->_receive['MsgType']) ? $this->_receive['MsgType'] : false;
}
/**
* 获取接收消息编号
*/
public function getRevId()
{
return isset($this->_receive['MsgId']) ? $this->_receive['MsgId'] : false;
}
/**
* 获取接收消息文本
* 通过语音识别接口,用户发送的语音,将会同时给出语音识别出的文本内容。(需申请服务号的高级接口权限)
*/
public function getRevText()
{
if(isset($this->_receive['Content'])) return trim($this->_receive['Content']);
elseif(isset($this->_receive['Recognition'])) return trim($this->_receive['Recognition']);
else return false;
}
/**
* 获取接收图片消息
*/
public function getRevImage()
{
if(isset($this->_receive['PicUrl'])){
return array(
'picUrl' => $this->_receive['PicUrl'], //图片链接
'mediaId' => $this->_receive['MediaId'] //图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
);
}
return false;
}
/**
* 获取接收语音消息
*/
public function getRevVoice()
{
if(isset($this->_receive['MediaId'])){
return array(
'mediaId' => $this->_receive['MediaId'], //语音消息媒体id,可以调用多媒体文件下载接口拉取数据。
'format' => $this->_receive['Format'] //语音格式,如amr,speex等
);
}
return false;
}
/**
* 获取接收视频消息
*/
public function getRevVideo()
{
if(isset($this->_receive['MediaId'])){
return array(
'mediaId' => $this->_receive['MediaId'], //视频消息媒体id,可以调用多媒体文件下载接口拉取数据。
'thumbMediaId' => $this->_receive['ThumbMediaId'] //视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
);
}
return false;
}
/**
* 获取用户地理位置
*/
public function getRevLocation()
{
if(isset($this->_receive['Location_X'])){
return array(
'locationX' => $this->_receive['Location_X'], //地理位置维度
'locationY' => $this->_receive['Location_Y'], //地理位置经度
'scale' => $this->_receive['Scale'], //地图缩放大小
'label' => $this->_receive['Label'] //地理位置信息
);
}
//开通了上报地理位置接口的公众号,用户在关注后进入公众号会话时,会弹框让用户确认是否允许公众号使用其地理位置。
//弹框只在关注后出现一次,用户以后可以在公众号详情页面进行操作。
elseif(isset($this->_receive['Latitude']))
{
return array(
'latitude' => $this->_receive['Latitude'], //地理位置纬度
'longitude' => $this->_receive['Longitude'], //地理位置经度
'precision' => $this->_receive['Precision'] // 地理位置精度
);
}
return false;
}
/**
* 获取接收链接消息
*/
public function getRevLink()
{
if(isset($this->_receive['Title'])){
return array(
'title' => $this->_receive['Title'], //消息标题
'description' => $this->_receive['Description'], //消息描述
'url' => $this->_receive['Url'] //消息链接
);
}
return false;
}
/**
* 获取接收事件类型
* 事件类型如:subscribe(订阅)、unsubscribe(取消订阅)、click
*/
public function getRevEvent()
{
if(isset($this->_receive['Event']))
{
return array(
'event' => strtolower($this->_receive['Event']),
'key'=> isset($this->_receive['EventKey']) ? $this->_receive['EventKey'] : ''
);
}
return false;
}
/**
* 设置回复文本消息
* @param string $content
* @param string $openid
*/
public function text($content='')
{
$textTpl = "
$this->_reply = sprintf($textTpl,
$this->getRevFrom(),
$this->getRevTo(),
Date::getTimeStamp(),
'text',
$content
);
return $this;
}
/**
* 设置回复音乐信息
* @param string $title
* @param string $desc
* @param string $musicurl
* @param string $hgmusicurl
*/
public function music($title, $desc, $musicurl, $hgmusicurl='')
{
$textTpl = '
//
$this->_reply = sprintf($textTpl,
$this->getRevFrom(),
$this->getRevTo(),
Date::getTimeStamp(),
'music',
$title,
$desc,
$musicurl,
$hgmusicurl
);
return $this;
}
/**
* 回复图文消息
* @param array
*/
public function news($data)
{
$count = count($data);
$subText = '';
if($count > 0)
{
foreach($data as $v)
{
$tmpText = '
$subText .= sprintf(
$tmpText, $v['title'],
isset($v['description']) ? $v['description'] : '',
isset($v['picUrl']) ? $v['picUrl'] : '',
isset($v['url']) ? $v['url'] : ''
);
}
}
$textTpl = '
$this->_reply = sprintf(
$textTpl,
$this->getRevFrom(),
$this->getRevTo(),
Date::getTimeStamp(),
$count,
$subText
);
return $this;
}
/**
* 回复消息
* @param array $msg
* @param bool $return
*/
public function reply()
{
header('Content-Type:text/xml');
echo $this->_reply;
exit;
}
/**
* 自定义菜单创建
* @param array 菜单数据
*/
public function createMenu($data)
{
if(!$this->access_token && !$this->checkAuth()) return false;
$result = curlRequest(self::API_URL_PREFIX.self::MENU_CREATE_URL.'access_token='.$this->access_token, $this->jsonEncode($data), 'post');
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return true;
}
return false;
}
/**
* 自定义菜单查询
*/
public function getMenu()
{
if(!$this->access_token && !$this->checkAuth()) return false;
$result = curlRequest(self::API_URL_PREFIX.self::MENU_GET_URL.'access_token='.$this->access_token);
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return $jsonArr;
}
return false;
}
/**
* 自定义菜单删除
*/
public function deleteMenu()
{
if(!$this->access_token && !$this->checkAuth()) return false;
$result = curlRequest(self::API_URL_PREFIX.self::MENU_DELETE_URL.'access_token='.$this->access_token);
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return true;
}
return false;
}
/**
* 获取用户基本信息
* @param string $openid 普通用户的标识,对当前公众号唯一
*/
public function getUserInfo($openid)
{
if(!$this->access_token && !$this->checkAuth()) return false;
$result = curlRequest(self::API_URL_PREFIX.self::USER_INFO_URL.'access_token='.$this->access_token.'&openid='.$openid);
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return $jsonArr;
}
return false;
}
/**
* 获取关注者列表
* @param string $next_openid 第一个拉取的OPENID,不填默认从头开始拉取
*/
public function getUserList($next_openid='')
{
if(!$this->access_token && !$this->checkAuth()) return false;
$result = curlRequest(self::API_URL_PREFIX.self::USER_GET_URL.'access_token='.$this->access_token.'&next_openid='.$next_openid);
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return $jsonArr;
}
return false;
}
/**
* 查询分组
*/
public function getGroup()
{
if(!$this->access_token && !$this->checkAuth()) return false;
$result = curlRequest(self::API_URL_PREFIX.self::GROUPS_GET_URL.'access_token='.$this->access_token);
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return $jsonArr;
}
return false;
}
/**
* 创建分组
* @param string $name 分组名字(30个字符以内)
*/
public function createGroup($name)
{
if(!$this->access_token && !$this->checkAuth()) return false;
$data = array('group' => array('name' => $name));
$result = curlRequest(self::API_URL_PREFIX.self::GROUPS_CREATE_URL.'access_token='.$this->access_token, $this->jsonEncode($data), 'post');
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return true;
}
return false;
}
/**
* 修改分组名
* @param int $id 分组id,由微信分配
* @param string $name 分组名字(30个字符以内)
*/
public function updateGroup($id, $name)
{
if(!$this->access_token && !$this->checkAuth()) return false;
$data = array('group' => array('id' => $id, 'name' => $name));
$result = curlRequest(self::API_URL_PREFIX.self::GROUPS_UPDATE_URL.'access_token='.$this->access_token, $this->jsonEncode($data), 'post');
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return true;
}
return false;
}
/**
* 移动用户分组
*
* @param string $openid 用户唯一标识符
* @param int $to_groupid 分组id
*/
public function updateGroupMembers($openid, $to_groupid)
{
if(!$this->access_token && !$this->checkAuth()) return false;
$data = array('openid' => $openid, 'to_groupid' => $to_groupid);
$result = curlRequest(self::API_URL_PREFIX.self::GROUPS_MEMBERS_UPDATE_URL.'access_token='.$this->access_token, $this->jsonEncode($data), 'post');
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return true;
}
return false;
}
/**
* 发送客服消息
* 当用户主动发消息给公众号的时候(包括发送信息、点击自定义菜单clike事件、订阅事件、扫描二维码事件、支付成功事件、用户维权),
* 微信将会把消息数据推送给开发者,开发者在一段时间内(目前为24小时)可以调用客服消息接口,通过POST一个JSON数据包来发送消息给普通用户,在24小时内不限制发送次数。
* 此接口主要用于客服等有人工消息处理环节的功能,方便开发者为用户提供更加优质的服务。
*
* @param string $touser 普通用户openid
*/
public function sendCustomMessage($touser, $data, $msgType = 'text')
{
$arr = array();
$arr['touser'] = $touser;
$arr['msgtype'] = $msgType;
switch ($msgType)
{
case 'text': // 发送文本消息
$arr['text']['content'] = $data;
break;
case 'image': // 发送图片消息
$arr['image']['media_id'] = $data;
break;
case 'voice': // 发送语音消息
$arr['voice']['media_id'] = $data;
break;
case 'video': // 发送视频消息
$arr['video']['media_id'] = $data['media_id']; // 发送的视频的媒体ID
$arr['video']['thumb_media_id'] = $data['thumb_media_id']; // 视频缩略图的媒体ID
break;
case 'music': // 发送音乐消息
$arr['music']['title'] = $data['title'];// 音乐标题
$arr['music']['description'] = $data['description'];// 音乐描述
$arr['music']['musicurl'] = $data['musicurl'];// 音乐链接
$arr['music']['hqmusicurl'] = $data['hqmusicurl'];// 高品质音乐链接,wifi环境优先使用该链接播放音乐
$arr['music']['thumb_media_id'] = $data['title'];// 缩略图的媒体ID
break;
case 'news': // 发送图文消息
$arr['news']['articles'] = $data; // title、description、url、picurl
break;
}
if(!$this->access_token && !$this->checkAuth()) return false;
$result = curlRequest(self::API_URL_PREFIX.self::MESSAGE_CUSTOM_SEND_URL.'access_token='.$this->access_token, $this->jsonEncode($arr), 'post');
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return true;
}
return false;
}
/**
* 获取access_token
*/
public function checkAuth()
{
// 从缓存中获取access_token
$cache_flag = 'weixin_access_token';
$access_token = cache($cache_flag);
if($access_token)
{
$this->access_token = $access_token;
return true;
}
// 请求微信服务器获取access_token
$result = curlRequest(self::API_URL_PREFIX.self::AUTH_URL.'appid='.$this->appid.'&secret='.$this->appsecret);
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0))
{
$this->error($jsonArr);
}
else
{
$this->access_token = $jsonArr['access_token'];
$expire = isset($jsonArr['expires_in']) ? intval($jsonArr['expires_in'])-100 : 3600;
// 将access_token保存到缓存中
cache($cache_flag, $this->access_token, $expire, Cache::FILE);
return true;
}
}
return false;
}
/**
* 微信oauth登陆->第一步:用户同意授权,获取code
* 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),
* snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
* 直接在微信打开链接,可以不填此参数。做页面302重定向时候,必须带此参数
*
* @param string $redirect_uri 授权后重定向的回调链接地址
* @param string $scope 应用授权作用域 0为snsapi_base,1为snsapi_userinfo
* @param string $state 重定向后会带上state参数,开发者可以填写任意参数值
*/
public function redirectGetOauthCode($redirect_uri, $scope=0, $state='')
{
$scope = ($scope == 0) ? 'snsapi_base' : 'snsapi_userinfo';
$url = self::CONNECT_OAUTH_AUTHORIZE_URL.'appid='.$this->appid.'&redirect_uri='.urlencode($redirect_uri).'&response_type=code&scope='.$scope.'&state='.$state.'#wechat_redirect';
redirect($url);
}
/**
* 微信oauth登陆->第二步:通过code换取网页授权access_token
*
* @param string $code
*/
public function getSnsAccessToken($code)
{
$result = curlRequest(self::SNS_OAUTH_ACCESS_TOKEN_URL.'appid='.$this->appid.'&secret='.$this->appsecret.'&code='.$code.'&grant_type=authorization_code');
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return $jsonArr;
}
return false;
}
/**
* 微信oauth登陆->第三步:刷新access_token(如果需要)
* 由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,
* refresh_token拥有较长的有效期(7天、30天、60天、90天),当refresh_token失效的后,需要用户重新授权。
*
* @param string $refresh_token 填写通过access_token获取到的refresh_token参数
*/
public function refershToken($refresh_token)
{
$result = curlRequest(self::SNS_OAUTH_REFRESH_TOKEN_URL.'appid='.$this->appid.'&grant_type=refresh_token&refresh_token='.$refresh_token);
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return $jsonArr;
}
return false;
}
/**
* 微信oauth登陆->第四步:拉取用户信息(需scope为 snsapi_userinfo)
* 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。
*
* @param string $access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
* @param string $openid 用户的唯一标识
*/
public function getSnsUserInfo($access_token, $openid)
{
$result = curlRequest(self::SNS_USERINFO_URL.'access_token='.$access_token.'&openid='.$openid);
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return $jsonArr;
}
return false;
}
/**
* 创建二维码ticket
* 每次创建二维码ticket需要提供一个开发者自行设定的参数(scene_id),分别介绍临时二维码和永久二维码的创建二维码ticket过程。
*
* @param int $scene_id 场景值ID,临时二维码时为32位整型,永久二维码时最大值为1000
* @param int $type 二维码类型,0为临时,1为永久
* @param int $expire 该二维码有效时间,以秒为单位。 最大不超过1800。
*/
public function createQrcode($scene_id, $type=0, $expire=1800)
{
if(!$this->access_token && !$this->checkAuth()) return false;
$data = array();
$data['action_info'] = array('scene' => array('scene_id' => $scene_id));
$data['action_name'] = ($type == 0 ? 'QR_SCENE' : 'QR_LIMIT_SCENE');
if($type == 0) $data['expire_seconds'] = $expire;
$result = curlRequest(self::API_URL_PREFIX.self::QRCODE_CREATE_URL.'access_token='.$this->access_token, $this->jsonEncode($data), 'post');
if($result)
{
$jsonArr = json_decode($result, true);
if(!$jsonArr || (isset($jsonArr['errcode']) && $jsonArr['errcode'] > 0)) $this->error($jsonArr);
else return $jsonArr;
}
return false;
}
/**
* 通过ticket换取二维码
* 获取二维码ticket后,开发者可用ticket换取二维码图片。请注意,本接口无须登录态即可调用。
* 提醒:TICKET记得进行UrlEncode
* ticket正确情况下,http 返回码是200,是一张图片,可以直接展示或者下载。
* 错误情况下(如ticket非法)返回HTTP错误码404。
*
* @param string $ticket
*/
public function getQrcodeUrl($ticket)
{
return self::SHOW_QRCODE_URL.'ticket='.urlencode($ticket);
}
/**
* 记录接口产生的错误日志
*/
public function error($data)
{
$this->errCode = $data['errcode'];
$this->errMsg = $data['errmsg'];
Log::info('WEIXIN API errcode:['.$this->errCode.'] errmsg:['.$this->errMsg.']');
}
/**
* 将数组中的中文转换成json数据
* @param array $arr
*/
public function jsonEncode($arr) {
$parts = array ();
$is_list = false;
//Find out if the given array is a numerical array
$keys = array_keys ( $arr );
$max_length = count ( $arr ) - 1;
if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //See if the first key is 0 and last key is length - 1
$is_list = true;
for($i = 0; $i if ($i != $keys [$i]) { //A key fails at position check.
$is_list = false; //It is an associative array.
break;
}
}
}
foreach ( $arr as $key => $value ) {
if (is_array ( $value )) { //Custom handling for arrays
if ($is_list)
$parts [] = $this->jsonEncode ( $value ); /* :RECURSION: */
else
$parts [] = '"' . $key . '":' . $this->jsonEncode ( $value ); /* :RECURSION: */
} else {
$str = '';
if (! $is_list)
$str = '"' . $key . '":';
//Custom handling for multiple data types
if (is_numeric ( $value ) && $value $str .= $value; //Numbers
elseif ($value === false)
$str .= 'false'; //The booleans
elseif ($value === true)
$str .= 'true';
else
$str .= '"' . addslashes ( $value ) . '"'; //All other things
// :TODO: Is there any more datatype we should be in the lookout for? (Object?)
$parts [] = $str;
}
}
$json = implode ( ',', $parts );
if ($is_list)
return '[' . $json . ']'; //Return numerical JSON
return '{' . $json . '}'; //Return associative JSON
}
/**
* 检验签名
*/
public function checkSignature()
{
$signature = HttpRequest::getGet('signature');
$timestamp = HttpRequest::getGet('timestamp');
$nonce = HttpRequest::getGet('nonce');
$token = $this->token;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
return ($tmpStr == $signature ? true : false);
}
/**
* 验证token是否有效
*/
public function valid()
{
if($this->checkSignature()) exit(HttpRequest::getGet('echostr'));
}
}

PHP는 현대적인 프로그래밍, 특히 웹 개발 분야에서 강력하고 널리 사용되는 도구로 남아 있습니다. 1) PHP는 사용하기 쉽고 데이터베이스와 완벽하게 통합되며 많은 개발자에게 가장 먼저 선택됩니다. 2) 동적 컨텐츠 생성 및 객체 지향 프로그래밍을 지원하여 웹 사이트를 신속하게 작성하고 유지 관리하는 데 적합합니다. 3) 데이터베이스 쿼리를 캐싱하고 최적화함으로써 PHP의 성능을 향상시킬 수 있으며, 광범위한 커뮤니티와 풍부한 생태계는 오늘날의 기술 스택에 여전히 중요합니다.

PHP에서는 약한 참조가 약한 회의 클래스를 통해 구현되며 쓰레기 수집가가 물체를 되 찾는 것을 방해하지 않습니다. 약한 참조는 캐싱 시스템 및 이벤트 리스너와 같은 시나리오에 적합합니다. 물체의 생존을 보장 할 수 없으며 쓰레기 수집이 지연 될 수 있음에 주목해야합니다.

\ _ \ _ 호출 메소드를 사용하면 객체를 함수처럼 호출 할 수 있습니다. 1. 객체를 호출 할 수 있도록 메소드를 호출하는 \ _ \ _ 정의하십시오. 2. $ obj (...) 구문을 사용할 때 PHP는 \ _ \ _ invoke 메소드를 실행합니다. 3. 로깅 및 계산기, 코드 유연성 및 가독성 향상과 같은 시나리오에 적합합니다.

섬유는 PHP8.1에 도입되어 동시 처리 기능을 향상시켰다. 1) 섬유는 코 루틴과 유사한 가벼운 동시성 모델입니다. 2) 개발자는 작업의 실행 흐름을 수동으로 제어 할 수 있으며 I/O 집약적 작업을 처리하는 데 적합합니다. 3) 섬유를 사용하면보다 효율적이고 반응이 좋은 코드를 작성할 수 있습니다.

PHP 커뮤니티는 개발자 성장을 돕기 위해 풍부한 자원과 지원을 제공합니다. 1) 자료에는 공식 문서, 튜토리얼, 블로그 및 Laravel 및 Symfony와 같은 오픈 소스 프로젝트가 포함됩니다. 2) 지원은 StackoverFlow, Reddit 및 Slack 채널을 통해 얻을 수 있습니다. 3) RFC에 따라 개발 동향을 배울 수 있습니다. 4) 적극적인 참여, 코드에 대한 기여 및 학습 공유를 통해 커뮤니티에 통합 될 수 있습니다.

PHP와 Python은 각각 고유 한 장점이 있으며 선택은 프로젝트 요구 사항을 기반으로해야합니다. 1.PHP는 간단한 구문과 높은 실행 효율로 웹 개발에 적합합니다. 2. Python은 간결한 구문 및 풍부한 라이브러리를 갖춘 데이터 과학 및 기계 학습에 적합합니다.

PHP는 죽지 않고 끊임없이 적응하고 진화합니다. 1) PHP는 1994 년부터 새로운 기술 트렌드에 적응하기 위해 여러 버전 반복을 겪었습니다. 2) 현재 전자 상거래, 컨텐츠 관리 시스템 및 기타 분야에서 널리 사용됩니다. 3) PHP8은 성능과 현대화를 개선하기 위해 JIT 컴파일러 및 기타 기능을 소개합니다. 4) Opcache를 사용하고 PSR-12 표준을 따라 성능 및 코드 품질을 최적화하십시오.

PHP의 미래는 새로운 기술 트렌드에 적응하고 혁신적인 기능을 도입함으로써 달성 될 것입니다. 1) 클라우드 컴퓨팅, 컨테이너화 및 마이크로 서비스 아키텍처에 적응, Docker 및 Kubernetes 지원; 2) 성능 및 데이터 처리 효율을 향상시키기 위해 JIT 컴파일러 및 열거 유형을 도입합니다. 3) 지속적으로 성능을 최적화하고 모범 사례를 홍보합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

Dreamweaver Mac版
시각적 웹 개발 도구

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전
