Thinkphp6接入微信支付V3版电商收付通简单示例_thinkphp6 微信支付视频教程-程序员宅基地

技术标签: 微信  php  thinkphp  

开发框架:thinkphp6

Api封装类:extend/library/WxPay.php

<?php
namespace library;

class WxPay
{
    //appId
    private $appId;
    //appSecret
    private $appSecret;
    //商户号
    private $mchId;
    //商户密钥
    private $mchKey;
    //本地路径
    private $path;
    //证书文件
    private $sslCert = 'apiclient_cert.pem';
    private $sslKey = 'apiclient_key.pem';
    private $platCert = 'plat_cert.json';
    //api地址
    private $rootUrl = 'https://api.mch.weixin.qq.com';
    //api证书序列号
    private $serialNo;
    //商户私钥
    private $privateKey;
    //v3密钥
    private $platKey;
    //平台证书序列号
    private $platSerialNo;
    //平台密钥
    private $platPublicKey;
    //加密方式
    private $signAlg = 'sha256WithRSAEncryption';
    private $schema = 'WECHATPAY2-SHA256-RSA2048';
    //主机头
    private $httpHeader;
    //请求类型
    private $method = 'GET';
    //api接口
    private $panel = '';
    //随机字符串
    public $nonce = '';
    //时间戳
    public $stamp = 0;
    //报文主体
    public $body = '';
    //签名
    public $signature = '';
    /**
     * 构造函数
     */
    public function __construct(array $config)
    {
        $this->appId = isset($config['appId']) ? $config['appId'] : '';
        $this->appSecret = isset($config['appSecret']) ? $config['appSecret'] : '';
        $this->mchId = isset($config['mchId']) ? $config['mchId'] : '';
        $this->mchKey = isset($config['mchKey']) ? $config['mchKey'] : '';
        $this->path = str_replace('\\', '/', ROOT_PATH);
        $this->sslCert = $this->path . (isset($config['sslCert']) ? $config['sslCert'] : $this->sslCert);
        $this->sslKey = $this->path . (isset($config['sslKey']) ? $config['sslKey'] : $this->sslKey);
        $this->platCert = $this->path . (isset($config['platCert']) ? $config['platCert'] : $this->platCert);
        $folder = dirname($this->platCert);
        if (!is_dir($folder)) {
            mkdir($folder, 0755, true);
        }
        $this->serialNo = isset($config['serialNo']) ? $config['serialNo'] : '';
        $this->platKey = isset($config['platKey']) ? $config['platKey'] : '';
        $this->getPrivateKey();
        $this->getCertificates();
    }
    /**
     * 预支付
     */
    public function prepay(array $data)
    {
        $data['appid'] = $this->appId;
        $data['mchid'] = $this->mchId;
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = '/v3/pay/transactions/jsapi';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * JSAPI支付
     */
    public function invoke($preid)
    {
        $this->body = 'prepay_id=' . $preid;
        $this->buildSignature();
        $data = array(
            'timeStamp' => $this->stamp,
            'nonceStr' => $this->nonce,
            'package' => $this->body,
            'signType' => 'RSA',
            'paySign' => $this->signature,
        );
        return $data;
    }
    /**
     * 原生支付
     */
    public function native(array $data)
    {
        $data['sp_appid'] = $this->appId;
        $data['sp_mchid'] = $this->mchId;
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = '/v3/pay/partner/transactions/native';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * 合单
     */
    public function combine(array $data)
    {
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = '/v3/combine-transactions/native';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * 退款
     */
    public function refund(array $data)
    {
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = '/v3/refund/domestic/refunds';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * 余额查询
     */
    public function balance($sub_mchid)
    {
        $this->method = 'GET';
        $this->panel = '/v3/ecommerce/fund/balance/' . $sub_mchid;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->get($url), true);
        return $result;
    }
    /**
     * 交易账单下载
     */
    public function bill($sub_mchid, $date = '')
    {
        if (!$date) {
            $date = date('Y-m-d', strtotime('-1 day'));
        }
        $this->method = 'GET';
        $this->panel = '/v3/bill/tradebill?bill_date=' . $date . '&sub_mchid=' . $sub_mchid . '&bill_type=ALL';
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->get($url), true);
        if (isset($result['download_url'])) {
            $this->panel = str_replace($this->rootUrl, '', $result['download_url']);
            $this->buildHeader();
            $result = $this->get($result['download_url']);
        }
        return $result;
    }
    /**
     * 上传图片
     */
    public function upload($file)
    {
        if (!$file && is_file($file)) {
            return false;
        }
        if (!in_array(pathinfo($file, PATHINFO_EXTENSION), array('jpg', 'png', 'bmp'))) {
            return false;
        }
        $file = str_replace('\\', '/', $file);
        $info = new \finfo(FILEINFO_MIME_TYPE);
        $mime = $info->file($file);
        $name = basename($file);
        $stream = file_get_contents($file);
        $meta = json_encode(array(
            'filename' => $name,
            'sha256' => hash_file('sha256', $file),
        ));
        $boundary = uniqid();
        $this->method = 'POST';
        $this->panel = '/v3/merchant/media/upload';
        $this->body = $meta;
        $this->httpHeader = array(
            'Accept: application/json',
            'User-Agent: ' . $_SERVER['HTTP_USER_AGENT'],
            'Authorization: ' . $this->buildAuthorization(),
            'Content-Type: multipart/form-data;boundary=' . $boundary,
        );
        $url = $this->rootUrl . $this->panel;
        $sep = '--' . $boundary . "\r\n";
        $out = $sep;
        $out .= 'Content-Disposition: form-data; name="meta";' . "\r\n";
        $out .= 'Content-Type: application/json' . "\r\n";
        $out .= "\r\n";
        $out .= $meta . "\r\n";
        $out .= $sep;
        $out .= 'Content-Disposition: form-data; name="file"; filename="' . $name . '";' . "\r\n";
        $out .= 'Content-Type: ' . $mime . "\r\n";
        $out .= "\r\n";
        $out .= $stream . "\r\n";
        $out .= '--' . $boundary . '--' . "\r\n";
        $result = json_decode($this->post($url, $out), true);
        return $result;
    }
    /**
     * 二级商户进件
     */
    public function applyment(array $data)
    {
        if (!isset($data['id_card_info']['id_card_name'])) {
            return false;
        }
        if (!isset($data['id_card_info']['id_card_number'])) {
            return false;
        }
        if (!isset($data['account_info']['account_name'])) {
            return false;
        }
        if (!isset($data['account_info']['account_number'])) {
            return false;
        }
        if (!isset($data['contact_info']['contact_name'])) {
            return false;
        }
        if (!isset($data['contact_info']['contact_id_card_number'])) {
            return false;
        }
        if (!isset($data['contact_info']['mobile_phone'])) {
            return false;
        }
        if (!isset($data['contact_info']['contact_email'])) {
            return false;
        }
        $data['appid'] = $this->appId;
        $data['id_card_info']['id_card_name'] = $this->encrypt($data['id_card_info']['id_card_name']);
        $data['id_card_info']['id_card_number'] = $this->encrypt($data['id_card_info']['id_card_number']);
        $data['account_info']['account_name'] = $this->encrypt($data['account_info']['account_name']);
        $data['account_info']['account_number'] = $this->encrypt($data['account_info']['account_number']);
        $data['contact_info']['contact_name'] = $this->encrypt($data['contact_info']['contact_name']);
        $data['contact_info']['contact_id_card_number'] = $this->encrypt($data['contact_info']['contact_id_card_number']);
        $data['contact_info']['mobile_phone'] = $this->encrypt($data['contact_info']['mobile_phone']);
        $data['contact_info']['contact_email'] = $this->encrypt($data['contact_info']['contact_email']);
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = '/v3/ecommerce/applyments/';
        $this->body = $data;
        $this->buildHeader(true);
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * 二级商户审核状态查询
     */
    public function auditState($no, $type = 0)
    {
        if (!$no) {
            return false;
        }
        $this->method = 'GET';
        $this->panel = '/v3/ecommerce/applyments/' . ($type ? 'out-request-no/' : '') . $no;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->get($url), true);
        return $result;
    }
    /**
     * 添加分账接收方
     */
    public function addReceivers(array $data)
    {
        if (!isset($data['name'])) {
            return false;
        }
        $data['appid'] = $this->appId;
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = '/v3/ecommerce/profitsharing/receivers/add';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * 分账
     */
    public function divide(array $data)
    {
        if (!$data && is_array($data)) {
            return false;
        }
        $data['appid'] = $this->appId;
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $this->method = 'POST';
        $this->panel = '/v3/ecommerce/profitsharing/orders';
        $this->body = $data;
        $this->buildHeader();
        $url = $this->rootUrl . $this->panel;
        $result = json_decode($this->post($url, $data), true);
        return $result;
    }
    /**
     * 敏感字段加密
     */
    public function encrypt($str)
    {
        $encrypted = '';
        if (openssl_public_encrypt($str, $encrypted, $this->platPublicKey, OPENSSL_PKCS1_OAEP_PADDING)) {
            $sign = base64_encode($encrypted);
        } else {
            throw new Exception('encrypt failed');
        }
        return $sign;
    }
    /**
     * 报文解密
     */
    public function decrypt($text, $assoc, $nonce)
    {
        $check = extension_loaded('sodium');
        if (false === $check) {
            return false;
        }
        $check = sodium_crypto_aead_aes256gcm_is_available();
        if (false === $check) {
            return false;
        }
        return sodium_crypto_aead_aes256gcm_decrypt(base64_decode($text), $assoc, $nonce, $this->platKey);
    }
    /**
     * 生成Header
     */
    private function buildHeader($usePlatSerial = false)
    {
        $this->httpHeader = array(
            'Accept: application/json',
            'User-Agent: ' . $_SERVER['HTTP_USER_AGENT'],
            'Content-Type: application/json',
        );
        if ($usePlatSerial) {
            $this->httpHeader[] = 'Wechatpay-Serial: ' . $this->platSerialNo;
        }
        $this->httpHeader[] = 'Authorization: ' . $this->buildAuthorization();
        if ($this->body) {
            $this->httpHeader[] = 'Content-Length: ' . strlen($this->body);
        }
    }
    /**
     * 生成Authorization
     */
    private function buildAuthorization()
    {
        $this->signer();
        $str = 'mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"';
        $str = sprintf($str, $this->mchId, $this->nonce, $this->stamp, $this->serialNo, $this->signature);
        return $this->schema . ' ' . $str;
    }
    /**
     * 签名生成器
     */
    private function signer()
    {
        $this->stamp = time();
        $this->nonce = $this->buildNonceStr();
        $message = $this->method . "\n" . $this->panel . "\n" . $this->stamp . "\n" . $this->nonce . "\n" . $this->body . "\n";
        openssl_sign($message, $signature, $this->privateKey, $this->signAlg);
        $this->signature = base64_encode($signature);
    }
    /**
     * 生成JSSDK签名
     */
    private function buildSignature()
    {
        $this->stamp = time();
        $this->nonce = $this->buildNonceStr();
        $message = $this->appId . "\n" . $this->stamp . "\n" . $this->nonce . "\n" . $this->body . "\n";
        openssl_sign($message, $signature, $this->privateKey, $this->signAlg);
        $this->signature = base64_encode($signature);
    }
    /**
     * 获取商户私钥
     */
    private function getPrivateKey()
    {
        if (is_file($this->sslKey)) {
            $this->privateKey = openssl_pkey_get_private(file_get_contents($this->sslKey));
        }
    }
    /**
     * 获取平台证书
     */
    private function getCertificates()
    {
        if (is_file($this->platCert)) {
            $json = file_get_contents($this->platCert);
            $data = json_decode($json, true);
            if (isset($data['serial_no'])) {
                $this->platSerialNo = $data['serial_no'];
            }
            if (isset($data['cipher'])) {
                $this->platPublicKey = $data['cipher'];
            }
        }
        if (!($this->platSerialNo && $this->platPublicKey)) {
            $this->method = 'GET';
            $this->panel = '/v3/certificates';
            $this->buildHeader();
            $url = $this->rootUrl . $this->panel;
            $result = json_decode($this->get($url), true);
            if ($result && isset($result['data']) && $result['data']) {
                $data = $result['data'][0];
                $serial_no = $data['serial_no'];
                $cert = $data['encrypt_certificate'];
                $cipher = $this->decrypt($cert['ciphertext'], $cert['associated_data'], $cert['nonce']);
                $this->platSerialNo = $serial_no;
                $this->platPublicKey = $cipher;
                $json = json_encode(array(
                    'serial_no' => $serial_no,
                    'cipher' => $cipher,
                ));
                file_put_contents($this->platCert, $json);
            }
        }
    }
    /*
     * 生成随机字符串
     */
    private function buildNonceStr($len = 32)
    {
        $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $str = '';
        for ($i = 0; $i < $len; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
    /*
     * get请求
     */
    private function get($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->httpHeader);
        $out = curl_exec($ch);
        curl_close($ch);
        return $out;
    }
    /*
     * post请求
     */
    private function post($url, $data = '')
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->httpHeader);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;
    }
    /**
     * 获取客户端ip
     */
    public function getClientIp()
    {
        if (getenv('HTTP_CLIENT_IP')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('HTTP_X_FORWARDED')) {
            $ip = getenv('HTTP_X_FORWARDED');
        } elseif (getenv('HTTP_FORWARDED_FOR')) {
            $ip = getenv('HTTP_FORWARDED_FOR');
        } elseif (getenv('HTTP_FORWARDED')) {
            $ip = getenv('HTTP_FORWARDED');
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return $ip;
    }
}

交易流程:

Step1:上传二级商户营业执照、身份证正反面照片(upload)

Step2:二级商户进件(applyment)

Step3:查询二级商户进件状态,审核通过后邀请二级商户签约(auditState)

Step4:添加分账接收方(addReceivers)

Step5:用户下单付款,指定分账信息(native、combine)

Step6:交易成功发起分账(divide)

使用示例:Sample.php

<?php
namespace app\[module]\controller;

use library\WxPay;
use think\App;

class Sample extends Base
{
    protected $app;
    private $wxpay;
    /**
     * 构造方法
     */
    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->wxpay = new WxPay(array(
            'appId' => '<appId>',
            'appSecret' => '<appSecret>',
            'mchId' => '<mchId>',
            'mchKey' => '<mchKey>',
            'serialNo' => '<serialNo>',
            'platKey' => '<platKey>',
        ));
    }
    /**
     * 上传图片示例
     */
    public function uploadImage()
    {
        $file = ROOT_PATH . 'sample.png';
        $result = $this->wxpay->upload($file);
        var_dump($result);
    }
    /**
     * 二级商户进件示例
     */
    public function applyment()
    {
        $data = array(
            'out_request_no' => '<内部编号>',
            'organization_type' => '<主体类型>',
            'business_license_info' => array(
                'business_license_copy' => '<上传营业执照得到的MediaID>',
                'business_license_number' => '<营业执照号>',
                'merchant_name' => '<商户名称>',
                'legal_person' => '<法人姓名>',
            ),
            'id_doc_type' => 'IDENTIFICATION_TYPE_MAINLAND_IDCARD',
            'id_card_info' => array(
                'id_card_copy' => '<上传身份证正面得到的MediaID>',
                'id_card_national' => '<上传身份证背面得到的MediaID>',
                'id_card_name' => '<身份证登记姓名>',
                'id_card_number' => '<身份证号>',
                'id_card_valid_time' => '<身份证有效期>',
            ),
            'need_account_info' => true,
            'account_info' => array(
                'bank_account_type' => '<银行账号类型>',
                'account_bank' => '<开户行>',
                'account_name' => '<银行账号开户名>',
                'bank_address_code' => '<开户行地区编号>',
                'bank_name' => '<银行全称>',
                'account_number' => '<银行账号>',
            ),
            'contact_info' => array(
                'contact_type' => '64[|65]',
                'contact_name' => '<超级管理员姓名>',
                'contact_id_card_number' => '<超级管理员身份证号>',
                'mobile_phone' => '<超级管理员手机号>',
                'contact_email' => '<超级管理员电子信箱>',
            ),
            'sales_scene_info' => array(
                'store_name' => '<经营网店名称>',
                'store_url' => '<经营网店URL地址>',
            ),
            'merchant_shortname' => '<商户简称>',
        );
        $result = $this->wxpay->applyment($data);
        var_dump($result);
    }
    /**
     * 二级商户审核状态查询示例
     */
    public function state()
    {
        $request_no = '202101010000';
        $result = $this->wxpay->auditState($request_no);
        var_dump($result);
    }
    /**
     * 添加分账方示例
     */
    public function addReceivers()
    {
        $data = array(
            'type' => 'MERCHANT_ID',
            'account' => '<二级商户号>',
            'name' => '<二级商户全称>',
            'relation_type' => 'SUPPLIER',
        );
        $result = $wxpay->addReceivers($data);
        var_dump($result);
    }
    /**
     * 原生支付示例
     */
    public function native()
    {
        $data = array(
            'sub_mchid' => '<二级商户的商户号>',
            'description' => '<商品描述>',
            'out_trade_no' => '<内部订单号>',
            'notify_url' => '<通知URL>',
            'settle_info' => array(
                'profit_sharing' => true,
            ),
            'amount' => array(
                'total' => '<订单总金额>',
                'currency' => 'CNY',
            ),
            'attach' => '<可选,附加数据>',
        );
        $result = $wxpay->native($data);
        var_dump($result);
    }
    /**
     * 合单支付示例
     */
    public function combine()
    {
        $data = array(
            'combine_appid' => '<合单发起方的appid>',
            'combine_mchid' => '<合单发起方的商户号>',
            'combine_out_trade_no' => '<合单支付总订单号>',
            'scene_info' => array(
                'payer_client_ip' => $this->wxpay->getClientIp(),
            ),
            'sub_orders' => array(
                array(
                    'mchid' => '<子单发起方的商户号>',
                    'attach' => '<附加数据>',
                    'amount' => array(
                        'total_amount' => 1,
                        'currency' => 'CNY',
                    ),
                    'out_trade_no' => '<子单商户订单号>',
                    'sub_mchid' => '<二级商户号>',
                    'description' => '<商品描述>',
                    'settle_info' => array(
                        'profit_sharing' => true,
                    ),
                ),
            ),
            'notify_url' => 'https://www.xxx.com/notify.php',
        );
        $result = $wxpay->combine($data);
        var_dump($result);
    }
    /**
     * 退款示例
     */
    public function refund()
    {
        $data = array(
            'sub_mchid' => '<二级商户号>',
            'transaction_id' => '<微信支付订单号>',
            'out_trade_no' => '<内部订单号>',
            'out_refund_no' => '<内部退款单号>',
            'amount' => array(
                'refund' => '<交易总金额>',
                'total' => '<退款金额>',
                'currency' => 'CNY',
            ),
        );
        $result = $wxpay->refund($data);
        var_dump($result);
    }
    /**
     * 分账示例
     */
    public function divide()
    {
        $data = array(
            'sub_mchid' => '<二级商户号>',
            'transaction_id' => '<微信支付订单号>',
            'out_order_no' => '<内部订单号>',
            'receivers' => array(
                array(
                    'type' => '<分账接收方类型>',
                    'account' => '<分账接收方账号>',
                    'amount' => '<分账金额>',
                    'description' => '<分账描述>',
                ),
            ),
            'finish' => true,
        );
        $result = $wxpay->divide($data);
        var_dump($result);
    }
    /**
     * 余额查询
     */
    public function balance()
    {
        $result = $wxpay->balance('<二级商户号>');
        var_dump($result);
    }
    /**
     * 下载账单
     */
    public function bill()
    {
        $date = date('Y-m-d');
        $result = $wxpay->bill('<二级商户号>', $date);
        var_dump($result);
    }
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sitetesty/article/details/120082276

智能推荐

超级简单python基于django框架仓库管理系统设计与实现mysql数据库(项目源码+数据库)_django三种角色-程序员宅基地

文章浏览阅读995次。1、项目介绍基于django框架的企业设备采购管理系统拥有三种角色:管理员、货主、采购主要实现功能有:货物大厅、我的订单、个人中心、货物管理、入库记录、出库记录、用户管理。2、项目技术后端框架:django前端框架:elementUI、jsp、css、JavaScript、JQuery3、开发环境IDE类型:IPyCharm数据库版本:MySql 8.0硬件环境:Windows 或者 Mac OS4、功能介绍用户登录用户注册仓库管理出库记录入库记录用户管理相关源码下载:请点击下载》》》.._django三种角色

POSIX多线程中的pthread_cond_wait() 函数_pthreads中wait函数-程序员宅基地

文章浏览阅读549次。由于工作站软件的移植牵涉到这方面的内容, 搜一最近一直在学习Linux线程方面的知识!由于这本书上没有将条件变量的问题,所以不能理解的一个函数就是pthread_cond_wait(). 今天终于有点明白了,赶快记下心得! 条件变量的结构为pthread_cond_t_pthreads中wait函数

poj1952(经典dp题)_“逢低吸”是股的一条成功诀,如成为一个成功的资者,就要守这条诀:“低吸纳,越低越-程序员宅基地

文章浏览阅读771次。点击打开题目链接下面是别处找来的中文翻译版【问题描述】 “逢低吸纳”是炒股的一条成功秘诀。如果你想成为一个成功的投资者,就要遵守这条秘诀:"逢低吸纳,越低越买"这句话的意思是:每次你购买股票时的股价一定要比你上次购买时的股价低.按照这个规则购买股票的次数越多越好,看看你最多能按这个规则买几次。给定连续的N天中每天的股价。你可以在任何一天购买一次股票,但是购买时的股价一_“逢低吸”是股的一条成功诀,如成为一个成功的资者,就要守这条诀:“低吸纳,越低越

详析Spring中依赖注入的三种方式_论述spring依赖注入中注解分类-程序员宅基地

文章浏览阅读298次。转自:http://www.jb51.net/article/93302.htm前言平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的_论述spring依赖注入中注解分类

数据结构_数组与广义表_矩阵的十字链表存储稀疏矩阵相加_十字链表储存稀疏矩阵的加法运算-程序员宅基地

文章浏览阅读2.6k次。十字链表做存储结构实现矩阵相加,这个功能简单的程序调试了N久,数度想放弃,但想想还是想坚持了下来,指针跳来跳去的快把我跳晕了,各种细节,比如删除节点后要修改相应节点的指针以确保能正常输出。终于调通了,一道坎总算过去了,示例通过后连加注释的勇气都没了。算了,先贴出来吧。"crosslist.h"#includeusing namespace std;#defin_十字链表储存稀疏矩阵的加法运算

Pyspider-程序员宅基地

文章浏览阅读257次。Pyspider是由国人(binux)编写的强大的网络爬虫系统Ptspider带有强大的WebUi / 脚本编辑器 / 任务监控器 / 项目管理器以及结果处理器。他支持多种数据库后端 / 多种消息队列 / Javascript 渲染页面爬去。使用起来非常方便基本功能提供了方便易用的 WebUi 系统,可视化的编写和调试爬虫提供爬去进度监控 / 爬去结果查看 / 爬虫项..._pyspider

随便推点

解决ubuntu18.04卡在“starting Gnome Display Manager“_start gnome display manager卡住-程序员宅基地

文章浏览阅读5.8k次,点赞5次,收藏24次。解决ubuntu18.04卡在"starting Gnome Display Manager"问题场景:在ubuntu安装NVIDIA驱动后,重启电脑后卡在“starting Gnome Display Manager”界面。解决方案:首先、进入ubuntu登陆界面里的ubuntu高级选项然后选择recover mode模式,或许你有不止一个,选最上面那个recover就行了。然后进入菜单界面由于我们是安装NVIDIA驱动导致的gnome启动不了,其实是gnome没有对应更新,所以需要_start gnome display manager卡住

模拟BBED修改文件头解决数据库Open验证问题_bbed 修改离线文件-程序员宅基地

文章浏览阅读295次。参考大神realkid4的博客http://blog.itpub.net/17203031/viewspace-2126665/做个实验发现点问题 做个记录环境说明SQL&gt; select * from v$version;BANNER----------------------------------------------------------------------..._bbed 修改离线文件

Nginx限制访问方式,禁用OPTIONS TRACE不安全方法_nginx 禁用trace方法-程序员宅基地

文章浏览阅读4.6k次。一、背景场景:jar包已经打包部署,项目源码不能修改,解决 curl -v -X TRACE 时200 漏洞解决方法, 从Nginx下手二、360安全要求,尽量用get和post的api的应用,禁用OPTIONS ,即对put,delete,tract等最不要使用,他们认为不安全。三、nginx中的配置: server {undefined listen 80; server_name localhost; #chars_nginx 禁用trace方法

cmd判断操作系统及创建快捷方式,安装包使用_cmd 判断 windows 环境-程序员宅基地

文章浏览阅读1.7k次。@echo offcopy config.xml "%USERPROFILE%\桌面\"rem 创建快捷方式Windows7 判断操作系统if "%OS%" == "Windows_NT" goto sys7if exist "%USERPROFILE%\「开始」菜单\程序\系统" goto okStartDIRmd "%USERPROFILE%\「开始」_cmd 判断 windows 环境

Linux下进程管理与控制_declared here extern __pid_t waitpid (__pid_t __pi-程序员宅基地

文章浏览阅读748次。1.创建进程:  extern __pid_t fork(void);  成功则在父进程中返回子进程的PID;在子进程中则返回0,以区别父子进程。  失败则在父进程中返回-1;  说明:子进程从创建后和父进程「同时」执行;竞争系统资源,子进程的执行位置为fork的返回位置。  extern __pid_t vfork(void);  成功则在父进程中返回子进程的PI_declared here extern __pid_t waitpid (__pid_t __pid, int *__stat_loc, int __

深圳市有关事假、病假、婚假、丧假、产假、哺乳假、生育看护假的规定_深圳事假最多可以请多久-程序员宅基地

文章浏览阅读4.9k次。http://www.szyc3z.com/xwa.asp?id=109335深圳市有关事假、病假、婚假、丧假、产假、哺乳假、生育看护假的规定作者:  发布时间:2013-5-22 10:03:00  阅读 1001 次打印本页 一、_深圳事假最多可以请多久