首页 > 后端开发 > 正文

PHP 如何能通过URL传递session

2025-03-21 21:02:20 | 我爱编程网

今天我爱编程网小编整理了PHP 如何能通过URL传递session相关内容,希望能帮助到大家,一起来看下吧。

本文目录一览:

PHP 如何能通过URL传递session

Thinkphp5.1微信小程序支付

研究了好几天,坑也遇到了,也百度了很久现在终于做完了,给大家分享出来,

我这个也是参考别人写的。有不明白的朋友可以问我

public function unifiedorder($order_no, $openid, $total_fee, $attach, $order_id, $user_id){

// 当前时间

$time = time();

// 生成随机字符串

$nonceStr = md5($time . $openid);

// API参数

$params = [

'appid' => $this->appid,                                  //微信分配的小程序id

'attach' => $attach,                                      //附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。

'body' => '会员卡',                                      //募捐描述

'mch_id' => $this->mchid,                        //微信支付分配的商户号

'nonce_str' => $nonceStr,                                  //随机字符串,32位以内

'notify_url' => $this->notify_url,                    //            base_url() . 'notice.php?s=/task/notify/order/wxapp_id/'.$wxapp_id, // 异步通知地址

'openid' => $openid,                                      //用户标识;trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识。

'out_trade_no' => $order_no,                              //商户账单号

'spbill_create_ip' => \request()->ip(),                    //终端IP;支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP

'total_fee' => (int)$total_fee * 100, // 价格:单位分              // 价格:单位分

'trade_type' => 'JSAPI',                                  //交易类型

];

// 生成签名

$params['sign'] = $this->makeSign($params);  //这个地方最坑,需要的是配置 1、appid和商户号必须是绑定的状态

// 请求API

$url = ' ';

$result = $this->post($url, $this->toXml($params));

$prepay = $this->fromXml($result);

//添加preapay_id

$data = [

'user_id' => $user_id,

'order_id' => $order_id,

'attach' => json_encode($attach),

'prepay_id' => $prepay['prepay_id'],

];

(new AppleWxPrepay())->addInfo($data);

// 请求失败

if ($prepay['return_code'] === 'FAIL') {

return [API_CODE_NAME => 2000004, API_MSG_NAME => $prepay['return_msg']];

}

if ($prepay['result_code'] === 'FAIL') {

return [API_CODE_NAME => 2000004, API_MSG_NAME => $prepay['err_code_des']];

}

// 生成 nonce_str 供前端使用

$paySign = $this->makePaySign($params['nonce_str'], $prepay['prepay_id'], $time);

return [

'prepay_id' => $prepay['prepay_id'],

'nonceStr' => $nonceStr,

'timeStamp' => (string)$time,

'paySign' => $paySign

];

}

/**

* 生成签名

* @param $values

* @return string 本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值

*/

private function makeSign($values)

{

//签名步骤一:按字典序排序参数

ksort($values);

$string = $this->toUrlParams($values);

//签名步骤二:在string后加入KEY

$string = $string . '&key=' . $this->apikey;

//签名步骤三:MD5加密

$string = md5($string);

//签名步骤四:所有字符转为大写

$result = strtoupper($string);

return $result;

}

/**

* 格式化参数格式化成url参数

* @param $values

* @return string

*/

private function toUrlParams($values)

{

$buff = '';

foreach ($values as $k => $v) {

if ($k != 'sign' && $v != '' && !is_array($v)) {

$buff .= $k . '=' . $v . '&';

}

}

return trim($buff, '&');

}

/**

* 模拟POST请求

* @param $url

* @param array $data

* @param bool $useCert

* @param array $sslCert

* @return mixed

*/

public function post($url, $data = [], $useCert = false, $sslCert = [])

{

$header = [

'Content-type: application/json; charset=UTF8'

];

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $url);

curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

curl_setopt($curl, CURLOPT_HEADER, false);

curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($curl, CURLOPT_POST, TRUE);

curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

if ($useCert == true) {

// 设置证书:cert 与 key 分别属于两个.pem文件

curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');

curl_setopt($curl, CURLOPT_SSLCERT, $sslCert['certPem']);

curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');

curl_setopt($curl, CURLOPT_SSLKEY, $sslCert['keyPem']);

}

$result = curl_exec($curl);

curl_close($curl);

return $result;

}

/**

* 输出xml字符

* @param $values

* @return bool|string

*/

private function toXml($values)

{

if (!is_array($values) || count($values) <= 0) {

return false;

}

$xml = "<xml>";

foreach ($values as $key => $val) {

if (is_numeric($val)) {

$xml .= "<" . $key . ">" . $val . "</" . $key . ">";

} else {

$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";

}

}

$xml .= "</xml>";

return $xml;

}

/**

* 将xml转为array

* @param $xml

* @return mixed

*/

private function fromXml($xml)

{

// 禁止引用外部xml实体

libxml_disable_entity_loader(true);

return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

}

/**

* 生成paySign

* @param $nonceStr

* @param $prepay_id

* @param $timeStamp

* @return string

*/

private function makePaySign($nonceStr, $prepay_id, $timeStamp)

{

$data = [

'appId' => $this->appid,

'nonceStr' => $nonceStr,

'package' => 'prepay_id=' . $prepay_id,

'signType' => 'MD5',

'timeStamp' => $timeStamp,

];

// 签名步骤一:按字典序排序参数

ksort($data);

$string = $this->toUrlParams($data);

// 签名步骤二:在string后加入KEY

$string = $string . '&key=' . $this->apikey;

// 签名步骤三:MD5加密

$string = md5($string);

// 签名步骤四:所有字符转为大写

$result = strtoupper($string);

return $result;

}

/*********************************微信回调**********************/

public function getNotify()

{

if (!$xml = file_get_contents('php://input')) {

$this->returnCode(50000001, 'Not found DATA');

}

// 将服务器返回的XML数据转化为数组

$data = $this->fromXml($xml);

$payLog = new ApplePayLog();

// 记录日志

$payLog->addInfo(['content'=>json_encode($xml)]);

$payLog->addInfo(['content'=>json_encode($data)]);

// 实例化账单模型

$OrderModel = new AppleOrder();

// 账单信息

$orderInfo = $OrderModel->getInfo(['id'=>$data['attach']],'*');

if (empty($orderInfo)) {

$this->returnCode(50000001, '账单不存在');

}

if($orderInfo['pay_status'] != 1 || !empty($orderInfo['pay_time'])){

$this->returnCode(50000001,'订单已支付,请勿再次支付');

}

// 保存微信服务器返回的签名sign

$dataSign = $data['sign'];

$return_code = $data['return_code'];

$result_code = $data['result_code'];

$data['body'] = '会员卡';

$data['spbill_create_ip'] = \request()->ip();

$data['notify_url'] = $this->notify_url;

// sign 与 s 参数 不参与签名算法

unset($data['sign']);

unset($data['transaction_id']);

unset($data['coupon_id']);

unset($data['coupon_type']);

unset($data['coupon_count']);

unset($data['coupon_fee']);

unset($data['time_end']);

unset($data['return_code']);

unset($data['result_code']);

unset($data['is_subscribe']);

unset($data['fee_type']);

unset($data['bank_type']);

unset($data['bank_type']);

// 生成签名

$sign = $this->makeSign($data);

// 判断签名是否正确  判断支付状态

if (($sign === $dataSign) && ($return_code == 'SUCCESS') && ($result_code == 'SUCCESS')) {

$OrderModel->startTrans();

try {

// 账单支付成功业务处理

$appleOrderInfo = $OrderModel->where(['id'=>$orderInfo['id']])->lock(true)->find();

$result = $appleOrderInfo->addInfo(['pay_status'=>2,'pay_time'=>time()],['id'=>$orderInfo['id']]);

if(!$result){

$OrderModel->rollback();

$this->returnCode(5000003, '修改订单失败,失败原因:'.$OrderModel->getError());

}

$appleUserModel = new AppleUser();

$appleUserInfo =  $appleUserModel->where(['openid'=>$orderInfo['openid']])->lock(true)->find();

$appleUser = $appleUserInfo->where(['openid'=>$orderInfo['openid']])->setInc('moxibustion',$orderInfo['moxibustion']);

if(!$appleUser){

$OrderModel->rollback();

$this->returnCode(5000003, '添加会员针灸次数失败,失败原因:'.$appleUserModel->getError());

}

}catch (\Exception $exception){

$OrderModel->rollback();

$this->returnCode(5000003, '操作失败,失败原因:'.$exception->getMessage());

}

$OrderModel->commit();

// 返回状态

die(json(['code'=>0,'支付成功']));

}

// 返回状态

$this->returnCode(2000003, '签名失败');

}

PHP 如何能通过URL传递session

Elasticsearch:为 Elasticsearch 8.x 引入新的 PHP 客户端

作者:Enrico Zimuel

Elasticsearch 8 的新 PHP 客户端已从头开始重写。 除了采用 PSR 标准外,我们还重新设计了架构并将 HTTP 传输层移到了外部。 由于 HTTPlug 库,现在还可以使用可插拔系统。

继续阅读以探索:

PHP 客户端的新架构和特性

如何使用 HTTP 消息的 PSR-7标准使用端点和管理错误

如何使用异步方法与 Elasticsearch 交互

旧客户端

elasticsearch-php 库是使用 PHP 编程 Elasticsearch 的官方客户端。这个库使用一个 main 客户端类公开了 Elasticsearch 的所有 400 多个端点。在这个库的第 7 版中,所有端点都使用函数公开——例如,index?API 映射到方法 Client::index()。

这些函数返回一个关联数组,该数组是来自 Elasticsearch 的 HTTP 响应的反序列化。通常,此响应由 JSON 消息表示。使用 PHP 的 json_decode() 函数将此消息转换为数组。

如果出现错误,客户端会根据问题抛出异常。例如,如果 HTTP 响应是 404,客户端会抛出 Missing404Exception。如果要检索 HTTP 响应本身,则需要使用以下代码从客户端获取最后一个响应:

1.$response = $client->info();2.$last = $client->transport->getLastConnection()->getLastRequestInfo();4.$request = $last['request']; // associative array of the HTTP request5.var_dump($request);7.$response = $last['response']; // associative array of the HTTP response8.echo $response['status']; // 2009.echo $response['body']; // the body as string

HTTP 请求和响应通过以下几种方法从 transport 层(客户端的属性)检索:getLastConnection() 和 getLastRequestInfo()。

这段代码不能提供良好的开发体验,因为关联数组 $response 的键非常多,来自 PHP 的 cURL 扩展的使用。

新的客户

我们从头开始构建新的 Elasticsearch-php 8 有很多原因:开发人员体验、新的 PHP 标准、更开放的架构和性能。 我爱编程网

安装了大约 7000 万次,我们不希望版本 8 有很多 BC 中断。我们使用向后兼容的方法提供与版本 7 相同的 API。这意味着你通常可以使用相同的代码连接到 Elasticsearch 并执行端点调用 。不同之处在于响应。 在版本 8 中,响应是 Elasticsearch 响应的对象,实现了 PSR-7 响应接口和 PHP 的 ArrayAccess 接口。

等一下 — 这不是 BC 的中断吗? 幸运的是,我们实现了 ArrayAccess 接口,你可以继续以数组的形式消费响应,如下所示:

?发现差异:命名空间已更改! 我们引入了 Elastic 根命名空间。 其他代码看起来相同,但引擎盖下有很大的变化。

正如我们所提到的,版本 8 中的 $response 是一个对象,而版本 7 中这是一个关联数组。 如果你想要与版本 7 完全相同的行为,你可以使用函数 $response->asArray() 将响应序列化为数组。

我们还提供 asObject()、asString() 和 asBool() 函数将主体序列化为 PHP 标准类 (stdClass) 的对象,作为字符串或布尔值(如果 2xx 响应则为 true,否则为 false)。

例如,你可以使用之前的 info() 端点,如下所示:

1.$client = ClientBuilder::create()2. ->setHosts(['localhost:9200'])3. ->build();4.$response = $client->info();6.echo $response['version']['number'];7.echo $response->version->number; // 8.0.09.var_dump($response->asObject()); // response body content as stdClass object10.var_dump($response->asString()); // response body as string (JSON)11.var_dump($response->asBool()); // true if HTTP response code 2xx

$response 能够作为实现 PHP 的 _get() 魔术方法的对象访问响应主体。

如果要读取 HTTP 响应,则不需要从 Client 对象中恢复最后一条消息; 你可以在 $response 本身中访问 PSR-7 消息,如下所示:

1.echo $response->getStatusCode();// 200, since $response is PSR-72.echo (string) $response->getBody(); // Response body in JSON

这是一个很大的优势,尤其是当你使用异步时。 事实上,如果你使用异步编程,则无法从客户端检索到最后的响应。 不能保证最后一个响应就是你要查找的响应(本文后面将详细介绍异步操作)

自动完成的端点参数

我们使用 Psalm 项目的类对象数组在 elasticsearch-php 版本 8 中添加了自动完成功能。 Psalm 是一个静态分析工具,允许开发人员使用特殊的 phpDoc 属性来修饰代码。 其中一个属性是@psalm-type,它可以指定关联数组的键类型。 我们使用标准的 phpDoc @param 应用了 Psalm 类型。 每个 PHP 客户端端点都有一个输入参数,即 $params 数组。 例如,这里报告的是 index() 端点部分:

1./**2.* Creates or updates a document in an index.3.*4.* @see @param array{7.* id: string, //Document ID8.* index: string, // (REQUIRED) The name of the index9.* wait_for_active_shards: string, // Sets the number of shard copies …10.* op_type: enum, // Explicit operation type. Defaults to `index` for requests…11.* refresh: enum, // If `true` then refresh the affected shards to make this operation…12.* routing: string, // Specific routing value13.* timeout: time, // Explicit operation timeout14.* version: number, // Explicit version number for concurrency control15.* version_type: enum, // Specific version type16.* if_seq_no: number, // only perform the index operation if the last operation…17.* if_primary_term: number, // only perform the index operation if the last operation…18.* pipeline: string, // The pipeline id to preprocess incoming documents with19.* require_alias: boolean, // When true, requires destination to be an alias…20.* pretty: boolean, // Pretty format the returned JSON response. (DEFAULT: false)21.* human: boolean, // Return human readable values for statistics. (DEFAULT: true)22.* error_trace: boolean, // Include the stack trace of returned errors. (DEFAULT: false)23.* source: string, // The URL-encoded request definition. Useful for libraries…24.* filter_path: list, // A comma-separated list of filters used to reduce the response.25.* body: array, // (REQUIRED) The document26.* } $params27.*/28. public function index(array $params = [])

所有参数都用名称(索引)指定,包括类型(字符串)和描述参数的注释(索引的名称)。 所需参数使用 REQUIRED 注释指定。

你可以使用以前的表示法在 IDE 中进行自动完成。 例如,使用 PhpStorm,你可以安装 deep-assoc-completion 免费插件以启用具有 @psalm-type 属性的 PHP 关联数组自动完成。

Elasticsearch PHP client 8.x deep-assoc-completion

Elasticsearch PHP client 8.x deep-assoc-completion_哔哩哔哩_bilibili

即使此版本仍在开发中,[elastic-transport-php]( Studio Code也可以使用 deep-assoc-completion。

可插拔架构

我们在版本 8 中所做的另一个更改是从库中拆分 HTTP 传输层。 我们创建了 该库基于可插拔架构,这意味着您可以将其配置为使用以下接口的特定实现:

PSR-18 客户端,使用 ClientInterface

一个节点池,使用 NodePoolInterface

PSR-3 记录器,使用 LoggerInterface

elasticsearch-php 版本 8 使用 elastic-transport-php 作为依赖项。 这意味着你可以使用自定义 HTTP 库、自定义节点池或自定义记录器连接到 Elasticsearch。

我们使用 HTTPlug 库来执行 PHP 应用程序中可用的 PSR-18 和 PSR-7 库的自动发现。 默认情况下,如果应用程序没有安装 HTTP 库,我们使用 Guzzle。

例如,你可以使用Symfony HTTP 客户端,如下所示:

1.use Symfony\Component\HttpClient\Psr18Client;3.$client = ClientBuilder::create()4. ->setHttpClient(new Psr18Client)5. ->build();

或者,你可以使用 Monolog 记录器库,如下所示:

1.use Monolog\Logger;2.use Monolog\Handler\StreamHandler;4.$logger = new Logger('name');5.$logger->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));6.$client = ClientBuilder::create()7. ->setLogger($logger)8. ->build();

有关如何自定义客户端的更多信息,请查看配置页面。

连接到 Elastic Cloud

Elastic Cloud 是 Elastic 提供的 PaaS 解决方案。 要连接到 Elastic Cloud,你只需要 Cloud ID 和 API 密钥。

可以在 Elastic Cloud 仪表板的我的部署页面中检索 Cloud ID。 API 密钥可以从安全页面设置中的管理部分生成。

你可以阅读 PHP 客户端文档的连接部分以获取更多信息。

收集 Cloud ID 和 API 密钥后,你可以使用 elasticsearch-php 连接到你的 Elastic Cloud 实例,如下所示:

1.$client = ClientBuilder::create()2. ->setElasticCloudId('insert here the Cloud ID')3. ->setApiKey('insert here the API key')4. ->build(); 默认安全

如果你在基础架构中安装了 Elasticsearch 8,则可以使用启用了 TLS(传输层安全)的 PHP 客户端。 Elasticsearch 8 默认提供安全性,这意味着它使用 TLS 来保护客户端和服务器之间的通信。

为了配置 elasticsearch-php 以连接到 Elasticsearch 8,你需要拥有证书授权文件 (CA)。

你可以通过不同的方式安装 Elasticsearch。 如果使用 Docker,则需要执行以下命令:

docker pull docker.elastic.co/elasticsearch/elasticsearch:8.1.0

安装 Docker 映像后,你可以使用单节点集群配置执行 Elasticsearch,如下所示:

1.docker network create elastic2.docker run --name es01 --net elastic -p 9200:9200 -p 9300:9300 -it docker.elastic.co/elasticsearch/elasticsearch:8.1.0

此命令创建一个弹性 Docker 网络并使用端口 9200(默认)启动 Elasticsearch。

当你运行 Docker 映像时,将为 Elastic 用户生成一个密码并将其打印到终端(你可能需要在终端中向后滚动一点才能查看它)。 你必须复制它才能连接到 Elasticsearch。

现在 Elasticsearch 正在运行,我们可以获得 http_ca.crt 文件证书。 使用以下命令从 Docker 实例复制它:

docker cp es01:/usr/share/elasticsearch/config/certs/http_ca.crt .

一旦我们有了在 Elasticsearch 启动期间复制的 http_ca.crt 证书和密码,我们就可以使用它进行如下连接:

1.$client = ClientBuilder::create()2. ->setHosts(['localhost:9200'])3. ->build();4.$response = $client->info();6.echo $response['version']['number'];7.echo $response->version->number; // 8.0.09.var_dump($response->asObject()); // response body content as stdClass object10.var_dump($response->asString()); // response body as string (JSON)11.var_dump($response->asBool()); // true if HTTP response code 2xx0 在异步模式下使用客户端

PHP 客户端提供了为每个端点执行异步调用的可能性。 在版本 7 中,你需要在作为端点参数传递的客户端密钥中指定一个特殊的 future => lazy,如下所示:

1.$client = ClientBuilder::create()2. ->setHosts(['localhost:9200'])3. ->build();4.$response = $client->info();6.echo $response['version']['number'];7.echo $response->version->number; // 8.0.09.var_dump($response->asObject()); // response body content as stdClass object10.var_dump($response->asString()); // response body as string (JSON)11.var_dump($response->asBool()); // true if HTTP response code 2xx1

前面的示例使用异步 HTTP 调用在 Elasticsearch 中索引 { "foo": "bar" } 文档。 $response 是一个 future,而不是实际的响应。

future 代表 future 的计算,并且充当占位符。 你可以像常规对象一样在代码周围传递 future。 当你需要结果值时,你可以解决 future。 如果 future 已经解决(由于某些其他活动),则这些值立即可用。 如果 future 还没有被解析,解析会阻塞,直到这些值变得可用(例如,在 API 调用完成之后)。

在版本 7 中,future 实际上是 RingPHP 项目的 Promise。 在版本 8 中,如果你想使用异步,你需要为您的 HTTP 客户端安装特定的适配器。 例如,如果你使用 Guzzle 7(elasticsearch-php 的默认 HTTP 库),则需要安装 php-http/guzzle7-adapter,如下所示:

1.$client = ClientBuilder::create()2. ->setHosts(['localhost:9200'])3. ->build();4.$response = $client->info();6.echo $response['version']['number'];7.echo $response->version->number; // 8.0.09.var_dump($response->asObject()); // response body content as stdClass object10.var_dump($response->asString()); // response body as string (JSON)11.var_dump($response->asBool()); // true if HTTP response code 2xx2

要使用异步调用执行端点,你需要使用 Client::setAsync(true) 函数启用它,如下所示:

1.$client = ClientBuilder::create()2. ->setHosts(['localhost:9200'])3. ->build();4.$response = $client->info();6.echo $response['version']['number'];7.echo $response->version->number; // 8.0.09.var_dump($response->asObject()); // response body content as stdClass object10.var_dump($response->asString()); // response body as string (JSON)11.var_dump($response->asBool()); // true if HTTP response code 2xx3

如果要为下一个端点禁用异步,则需要再次将 setAsync 设置为 false。

异步调用的响应是 HTTPlug 库的 Promise 对象。 这个 Promise 遵循 Promises/A+ 标准。 Promise 代表异步操作的最终结果。

要获得响应,你需要等待该响应到达。 这将阻塞等待响应的执行,如下所示:

1.$client = ClientBuilder::create()2. ->setHosts(['localhost:9200'])3. ->build();4.$response = $client->info();6.echo $response['version']['number'];7.echo $response->version->number; // 8.0.09.var_dump($response->asObject()); // response body content as stdClass object10.var

PHP 如何能通过URL传递session

我爱编程网(https://www.52biancheng.com)小编还为大家带来PHP 如何能通过URL传递session的相关内容。

你将session的值放在地址参数就可以了,
$_SESSION ['id']
另外, SESSION 是全局的, 可以不用地址带参数传递的, 只要SESSION注册这个key就可以了

以上就是PHP 如何能通过URL传递session全部内容,更多相关信息,敬请关注我爱编程网。更多相关文章关注我爱编程网:www.52biancheng.com

免责声明:文章内容来自网络,如有侵权请及时联系删除。
标签: PHP
与“PHP 如何能通过URL传递session”相关推荐