【終了】阿珏Blog三周年特別記念イベント

2016年9月19日、初めてのドメインとサーバーを購入し、ブログの構築を始めました。 たくさんのことを経験し、たくさんの人々と出会い、たくさんの記事を書いてきました。 瞬く間にブログが誕生してから1089日が経ち、もうすぐ3周年を迎えます…… 特別な記念イベントを開催して、長年私を支えてくれた仲間たちに感謝を伝えたいと思います! イベント期間:9月13日~9月19日 イベント場所:このブログのコメント欄(本ページ) イベント賞品:二次元福袋&お菓子詰め合わせ&その他ミステリアスなアイテム。あなたが正統なヨーロッパ人の血を引いているか試す時が来ました! 参加方法その1:阿珏Blog三周年活動 - 萌音社区 参加方法その2:ご自身のブログで「阿珏ちゃんをどう評価するか」というテーマの記事を投稿してください。阿珏への祝福、阿珏のブログへの評価、阿珏に言いたいこと、阿珏との思い出など、何でも書いてください。もし阿珏を感動させることができたら、おめでとうございます、当選です! **賞品の受け取り方法 ** 阿珏から当選の通知が届いたら、コメント時に使用したメールアドレスから master@moeins.cn または admin@52ecy.cn 宛に、以下の内容をプライベートメッセージでお送りください。 お届け先住所、受取人氏名、受取人の連絡先電話番号 任意項目:性別、年齢、恋人の有無、自撮り写真、スマートフォンの機種など。福袋の中身の参考にさせていただきます。 すべてのやり取りは非公開で行われ、第三者に情報が漏れることはありません。 配送業者はランダムで、全世界送料無料です。業者の指定はできません。もしお住まいの地域で受け取れなかった場合は…私には関係ありませんので悪しからず。 賞品はイベント終了後、7営業日以内に発送を手配します。 **イベントルール ** 知り合い限定 個人ブログをお持ちのブロガーさん限定 この記事を読んだ方限定 人柄が良い方限定 イケメン限定 可愛い人限定 私がルールだ! 福袋プレビュー(以下の内容が含まれますが、これに限りません) フィギュア、ぬいぐるみ、キーホルダー、ペン、イヤホン、カードステッカー、缶バッジ、ポストカード、ノート、扇子、ネックレス、スマホフィルム、ブレスレット、指輪、マット、ミニクッション、マスコット、変身ステッキ、ZWB、H漫画、彼女、ちまき、月餅、ゴミ、カード、阿珏ちゃんなど。 これらの賞品の中から1つ、または複数が入っています。ポストカードは100%当選し、阿珏があなたに宛てて手書きしたメッセージも付いてきます。 賞品はどれも高価なものではありませんが、阿珏からのささやかな気持ちです。これまで長い間、私を応援し、支えてくれた仲間たちに心から感謝しています。 皆さん、中秋節おめでとうございます。楽しんでくださいね~ どんどんコメントしてください~

2019年9月13日 · 1 分 · MoeJue

初音ミク、12周年のお誕生日おめでとう!

初音ミク「マジカルミライ 2019」ライブ - フューチャーサーカス 姫殿下にご挨拶! 等身大のミクちゃん あっ、床が滑って転んじゃった 初音ミク ポストカードコレクション 予告:今月はブログ3周年記念イベント。これらのポストカードを発送する予定です………続く

2019年9月2日 · 1 分 · MoeJue

サボっていた主が、新版の三合一を持って帰ってきました。

5月20日の告白以来、ハト主は行方不明の状態が続いていました……. 何ヶ月ぶりか分かりませんが、三合一がまた更新されました。2ヶ月前にグループで立てた目標を、今日達成しました。間の2ヶ月間何をしていたかは聞かないでください-.-(大規模なハトの集会に参加するのに忙しかった) 正文 ネットワーク認識が頻繁にダウンし、非常に不安定であるというフィードバックを多くの仲間から受けていたため、今回特別にローカル認識を更新しました。 1G以上のメモリを搭載したマシンへのインストールを推奨します。推奨構成は2コア2G、最適構成は16コア32Gです [#手動顔文字] v2.0 ローカルQRコード認識と生成を追加 ネットワーク認識インターフェースを削除 既知のバグを修正 その他のいくつかの詳細な最適化 詳細な説明とインストールチュートリアルは、こちらをクリックして以前のバージョンをご覧ください。 新しいバージョンのウェブサイトはすべて古いバージョンのデータを保持しており、以前のユーザーの使用には影響せず、スポンサー版のデータとも同期されています。 スポンサー版 旧バージョンの海賊版が横行していたため、新版の三合一にはスポンサー版が追加されました。 デモサイト:https://qr.moeins.cn スポンサー版の主な特徴: QRコードの認識と生成を最適化し、認識精度を大幅に向上させ、認識速度を高速化し、CPUとメモリを占有せず、より安定しています。 21種類の三合一生成テンプレートを新規追加し、無限拡張をサポートします。追加チュートリアルは文末にあります。 外部APIインターフェースを新規追加しました。このプログラムに限定されず、どのプログラムからでも呼び出し可能です。 入手方法: こちらをクリックして18.88元以上をプロジェクトに寄付すると、決済コード三合一のスポンサー限定版を入手できます。ぜひお試しください! スポンサー版に関するいくつかの小さな説明(これまでは特に説明していませんでした) これまでのところ、私のすべてのスポンサー版プロジェクトはドメインに縛られず、暗号化されておらず、自由に拡張でき、二次開発をサポートしており、スポンサー金額も低く設定されています。そのため、スポンサーしてくださった方々は、入手したソースコードを安易に共有しないようお願いいたします。これは作者への敬意であり、ご自身の権利の保護でもあります。売買関係ではないため、重大なバグがない限り、作者は不定期に更新するか、無期限に更新を延期する場合があります。小さな問題が発生した場合、作者が空いている時間であれば指導や修正を手伝う用意がありますが、大規模な新機能の追加といった場合には、協力を拒否するか、別途料金をいただく権利があります。 スポンサー版テンプレート拡張チュートリアル テンプレートの推奨サイズは:900*1200 テンプレート画像を/public/static/images/template/テンプレートディレクトリに配置します。注意点として、中国語名を使用せず、jpg拡張子のみをサポートします。 ルートディレクトリのconfig.phpにあるqr_template項目に関連データを以下のような形式で設定します。 '001' => [ 'name' => '默认模板', 'data' => [ 150,200 ], 'title' => true, 'size' => 20 ] パラメータ説明 名称 変数名 必須 型 例 説明 テンプレートID なし はい int 001 テンプレートのファイル名。数字を推奨し、重複不可。 エイリアス name はい string デフォルトテンプレート フロントエンドに表示されるテンプレートのエイリアス X,Y data はい array [150,200] QRコード生成の左上隅の開始X(横座標)、Y(縦座標)座標。負の値は不可で、テンプレートサイズより小さいこと。 テンプレートタイトル title いいえ bool false テンプレートタイトルを有効にするかどうか。テンプレートがサポートしている場合(デフォルトテンプレートなど)に使用。空でも可。 サイズ size いいえ int 20 QRコードの生成サイズ。デフォルトは20。空でも可。 はい、とても簡単です!

2019年8月4日 · 1 分 · MoeJue

私は二次元が好きです。

二次元が好きだ、 あの世界が好きだから。 その純粋さに感動し、 その夢に励まされ、 そのひたむきさに勇気づけられる。 夢のような、存在するかもしれないし、しないかもしれない、そんな美しいものたち。 三次元の世界では、その多くがもう見つけられない。 次元のトンネルを抜けられたら、 愛する人たちと一緒にいられるのに。 でも、次元は超えられないから、 僕はいつも二次元と三次元の間を彷徨っている。 どんなに君を愛していても、 やっぱり「ごめんね」としか言えない。 だって僕は、三次元に生きているから……

2019年5月20日 · 1 分 · MoeJue

ミニプログラムアーキテクチャ

皆さんがミニプログラムをどのように書いているかは分かりませんが、数ヶ月前にWeChatミニプログラムを書いていた時、自分で考えたアーキテクチャ、あるいはフレームワークと呼べるものがあります。 WeChatネイティブのアーキテクチャは次のようになっています。 ├── app.js ├── app.json ├── app.wxss ├── pages │ │── index │ │ ├── index.wxml │ │ ├── index.js │ │ ├── index.json │ │ └── index.wxss │ └── logs │ ├── logs.wxml │ └── logs.js └── utils なぜWeChatネイティブの書き方を使わないのか? ミニプログラムはスマホアプリに似ていて、tabBarがありますよね。WeChat公式のtabBarはapp.jsonでグローバルに設定されます。一般的な開発では何の問題もありませんが、複雑なtabBarを実装する場合、公式のネイティブな方法では実現できず、動的に読み込むこともできません。例えば、ある動画アプリの中央にある撮影・録画機能のようなものです。 これは、公式が提供するtabBarを使えず、自作する必要があることを意味します。 最初の私のアプローチは、ネイティブの構造を維持しつつ、tabBarだけを自作するというものでした。そのため、ページのコードはすべて1つのファイルに書き、デフォルトで最初の画面を表示し、他は非表示にします。ページを切り替える際に、対応するページを表示し、他を非表示にして、データを動的にレンダリングします。しかし、これには問題がありました。小規模なプロジェクトなら大した問題はありませんが、大規模なプロジェクトでコード量が膨大になると、すべてを1つのファイルに書くのは後のメンテナンスが困難になります。そのため、この方法は最終的に却下されました。 その後、ページの切り替え方法を(wx.switchTabなどを使った)画面遷移に変更し、異なるページのコードを別々のファイルに分けました。しかし、まだ問題がありました。切り替え時に画面がちらつくのです。ページを切り替えるたびに、まるで新しいウェブページを開くかのように、tabBarが再レンダリングされるため、ちらつきが発生します。これも却下です。 そこで、現在の全く新しいアーキテクチャ方式が生まれました: /pages/index/以下のファイルをすべてエントリーファイル(JSエントリー、CSSエントリー、ビューエントリー)として定義します。異なるページのファイルは、管理しやすいように、やはり別の場所に置きます。新しくtemplateというフォルダを作成し、異なるページ間のコードを格納します。その構造は公式の単一ページの構造と同じです。 ルートディレクトリのapp.jsはグローバル関数を格納するために使用し、他のページからはgetApp()で呼び出すだけです。 JSのエントリーファイル const app = getApp(); var index_js = require("../../template/index/index.js"); var types_js = require("../../template/types/types.js"); var Global_Data = []; Page({ data: { active: 0, show: { index: true, types: false, course: false, user: false } }, onLoad(options) { this.setData({ Global_Data: index_js.getData() }) }, // 下部ナビゲーションの切り替え tabbar_onChange(event) { var key = ''; this.data.show = { index: false, types: false, course: false, user: false }; console.log(event) switch (event.detail) { case 0: key = 'index'; Global_Data = index_js.getData(); break; case 1: key = 'types'; Global_Data = types_js.getData() break; case 2: key = 'course'; Global_Data = index_js.getData(); break; case 3: key = 'user'; Global_Data = index_js.getData(); break; } this.data.show[key] = true; console.log(Global_Data) this.setData({ show: this.data.show, Global_Data: Global_Data }) }, }); wxmlエントリーファイル ...

2019年5月17日 · 2 分 · MoeJue

フォームをスマートに送信するには

これは非常に基本的なHTMLフォームの送信に関する問題ですが、非常に実用的なテクニックでもあります。 私の業務シーンは次のとおりです: inputを動的に作成できるフォームです。下の図のように。 これは、inputのnameを固定値にできないことを意味します。さもなければ、間違いなく上書きされてしまいます。 1つ目は、従来の一般的な送信方法で、送信する各inputに一意のnameを付けます。 ...... ブラウザが送信したデータをキャプチャした形式は次のようになります。 サーバー側で取得して出力するとこのようになり、バックエンドでのデータ処理には非常に不親切です。 2つ目は、配列形式でのフォーム送信です。 ...... ブラウザとバックエンドでの出力はそれぞれ次のようになります。 よく見ると、送信されたnameの値が変化し、同じような?配列?になっていることがわかります。 バックエンドに送信すると、データが以前よりもずっと整理されていることがわかります。 ただし、ここで注意すべき点は、送信する配列のキーに引用符を使用する必要はないということです。さもなければ、引用符もキーの一部になってしまいます。 もちろん、実際の開発では、送信するグループの数(上記の1、2、3のような)が不確定で、フロントエンドで自由に追加できるという問題に遭遇することもあります。このような場合、どうやって配列を使ってこれらの内容を送信すればよいのでしょうか? 以下が私の業務での実際の解決策です このようにすれば、2次元配列のキーを自分で管理する必要がなくなり、ブラウザが自動的に生成してくれます。 バックエンドで受信したデータはこのようになり、非常に処理しやすくなります。 この方法は、不確定な数の関連データセットをまとめて送信する場合に適しています。 一件落着!〜

2019年5月6日 · 1 分 · MoeJue

人生はなぜいつも私に辛く当たるのか?

パジャマでデリバリーを受け取りに出かけたら、 知り合いには会いたくなかったのに、よりによってたくさんの知り合いに見られてしまった。 映画を見ている時に眠くて、 途中でトイレに行ったら、ちょうど見どころのシーンを見逃してしまった。 観光地でチケットを買うために並んだら、 どちらの列に並んでも、もう片方の列の方がいつも早く進む…言うまでもなく、雨が降るたびに傘を持たずに出て、傘を持っている時には雨が降らない、 買ったばかりのものが値下げされ、授業をサボったらすぐに点呼され、 欲しいカードは引けず、好きな人には好きになってもらえない…なぜいつも人生は私に意地悪をするのだろう? 運命のせいではなく、全ては「マーフィーの法則」のせいだ。 マーフィーの法則 ある事柄が起こる確率がどんなに小さくても、 常に起こる可能性があり、 そして、ある状況が起こることを心配すればするほど、 それはより起こりやすくなる。 俗に言うように、 恐れていることほど、起こりやすい。 ウェブサイトがどんどん良くなり、目立つと攻撃されやすいと心配していたら、 案の定DDoSやCC攻撃を受けた。 サーバーがまだ「丸裸」の状態で、ハッカーに狙われるのを恐れていたら、 うっかりしているうちに、トロイの木馬やウイルスに深く「縛り付けられて」しまった。 ビジネスのセキュリティを心配し、毎日細心の注意を払っていたのに、 まさか、操作ミスでデータを失ってしまった…なぜいつもこのような問題が起こるのだろう? なぜなら、確率自体が一種の「オカルト」だからだ。 最先端のデータ事件や、プログラマーがデータベースを削除して逃走する事件のように、 発生する前には誰も予測できないが、 一度遭遇すれば100%であり、その打撃は特に致命的だ… そして残念なことに、これらの結果は本来避けられたはずなのだ…想像してみてほしい、もしあなたが事前にセキュリティ対策をしっかり行っていれば、 DDoSやCC攻撃に打ち負かされることはなかっただろう。 そして、ファイアウォールを導入し、システムパッチを適用していれば、 ハッカーもつけ入る隙はなかっただろう。 さらに極端な話、たとえプログラマーがデータベースを削除して逃走したとしても、 スナップショットバックアップが残っていれば、復旧の余地があるだろう… だから、たとえ低確率の「危険な」事象であっても、 私たちは同様に無視してはならない。 あらゆる準備を整えてこそ、 99%の安全を確保し、1%の損害を避けることができるのだ。大規模なトラフィック攻撃が来たら、 DDoS高防 / BGP高防IPで侵入を隔離し、 ウェブページの改ざんやアクセス速度の低下の問題に遭遇したら、 WebアプリケーションファイアウォールやCDNアクセラレーションで解決できる。 データセキュリティと通信暗号化は、クラウドディスクやSSL証明書に任せればよい。もし上記の点をすべて実行できれば、 おめでとうございます。ウェブサイトのセキュリティのフラグはすでに達成され、 たとえ不運にも「被害に遭った」としても、 安心して、何も恐れることはないでしょう。

2019年4月22日 · 1 分 · MoeJue

水着の女の子はやっぱり最高

冴えない彼女の育てかた – 澤村・スペンサー・英梨々 – 略称エリカ ゆうパック 開封 外箱を一周、外箱もコレクションする価値がある 見てはいけないものを見てしまった 箱から取り出す、水着がちゃんと着れてないみたい、これは…(目を覆う)子供には見せられない、モザイク処理、モザイク処理 やっと女の子に水着を着せてあげられた この足は白い、舐めたい 一周 小さな八重歯が最高 角度が刁 一人称(笑-。- 開封終了、完璧Ψ( ̄∀ ̄)Ψ

2019年4月19日 · 1 分 · MoeJue

よく使われる機能のクエリSQL

1、シーン:ある選手のランキングと、1つ上の順位の選手との票差をクエリする 方法2(重複を除外してソートし、自分より票の少ない数をクエリする) $temp = DB::fetch_first(“SELECT distinct total+jewel_vote+forge_vote ,COUNT(*)+1 AS RANK FROM " . DB::table(‘vote_competition’) .” WHERE total+jewel_vote+forge_vote>" . $competition[‘all’] . " and aid={$aid} ORDER by forge_vote desc"); $rank = $temp[‘RANK’]; 1つ上の順位の選手の票数を直接クエリすることはできない if ($temp[’total+jewel_vote+forge_vote’]) { //ここでクエリされるのは1位の選手との票差です $up = $temp[’total+jewel_vote+forge_vote’]-$competition[‘all’]; } 方法1(変数を定義して累加ソート) $temp = DB::fetch_all(“SELECT a.cid,a.total,a.forge_vote,a.jewel_vote,(@rowNum:=@rowNum+1) AS rank FROM pre_vote_competition AS a, (SELECT (@rowNum :=0) ) b WHERE aid={$aid} ORDER BY (a.total+a.forge_vote+a.jewel_vote) DESC “); foreach ($temp as $key => $value) { if ($value[‘cid’] == $cid) { //現在の自分のランキング $rank = $value[‘rank’]; if ($up) { $up = $up - ($value[’total’] + $value[‘forge_vote’] + $value[‘jewel_vote’]); } break; } //1つ上の順位の選手との票差 $up = $value[’total’] + $value[‘forge_vote’] + $value[‘jewel_vote’]; } ...

2019年4月10日 · 3 分 · MoeJue

WeChatでログイン

ドキュメント:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319 WeChatの認証ログインは、QQやSinaなどのプラットフォームの認証ログインとほぼ同じで、いずれもOAuth2.0認証方式を採用しています。 WeChatの認証は2種類に分かれています: サイレント認証 ポップアップ認証、ユーザーの手動同意が必要 2種類のscopeの違いについて snsapi_baseをscopeとして開始されるウェブ認証は、ページにアクセスしたユーザーのopenidを取得するためのもので、サイレント認証であり、自動的にコールバックページにリダイレクトされます。ユーザーは直接コールバックページ(通常は業務ページ)にアクセスしたように感じます。 snsapi_userinfoをscopeとして開始されるウェブ認証は、ユーザーの基本情報を取得するためのものです。この認証はユーザーの手動同意が必要ですが、一度同意すれば、公式アカウントをフォローしていなくても、認証後にそのユーザーの基本情報を取得できます。 ユーザー管理関連のAPIにおける「ユーザー基本情報取得API」は、ユーザーが公式アカウントとメッセージのやり取りをするか、フォローした後のイベントプッシュがあって初めて、ユーザーのOpenIDに基づいて基本情報を取得できます。このAPIを含む他のWeChat APIは、すべて対象ユーザー(openid)が公式アカウントをフォローしている場合にのみ、正常に呼び出すことができます。 具体的には、ウェブ認証のフローは4つのステップに分かれています: ユーザーを認証ページに誘導し、同意を得てcodeを取得する codeを使用してウェブ認証用のaccess_tokenを取得する(基本サポートのaccess_tokenとは異なる) 必要に応じて、開発者はウェブ認証用のaccess_tokenを更新し、期限切れを回避する ウェブ認証用のaccess_tokenとopenidを使用してユーザーの基本情報を取得する(UnionIDメカニズムをサポート) 以下はカプセル化されたWeChat操作クラスです。access_tokenとticketを保存するために2つのデータテーブルを使用します。これらには有効期限があり、1日あたりのリクエスト数に上限があるため、開発者は自身で保存する必要があります。 <?php /** * WeChat操作テーブル * wxtoken テーブル構造 * id * access_token * addtime * wxticket テーブル構造 * id * ticket * addtime */ class WX { private $appid; private $appserect; private $curl; private $msg; protected $errs = array( '-1' => 'システムがビジーです。開発者はしばらくしてから再試行してください', '0' => 'リクエスト成功', '40001' => 'AppSecretが間違っているか、この公式アカウントのものではありません。開発者はAppSecretが正しいことを確認してください', '40002' => 'grant_typeフィールドの値がclient_credentialであることを確認してください', '40164' => 'APIを呼び出したIPアドレスがホワイトリストにありません。APIのIPホワイトリストで設定してください。', ); function __construct($appid, $appserect) { $this->appid = $appid; $this->appserect = $appserect; $this->curl = new Curl(); } /* WeChatウェブ認証ログイン 公式アカウント設定 - 機能設定 - ウェブ認証ドメインでの設定が必要 第一歩:ユーザーが認証に同意し、codeを取得 scope : snsapi_base openidのみ取得可能、直接リダイレクト snsapi_userinfo */ public function getCode($redirect_uri, $scope = 'snsapi_userinfo',$state = '1') { $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appid}&redirect_uri={$redirect_uri}&response_type=code&scope={$scope}&state={$state}#wechat_redirect"; header("Location:{$url}"); exit; } /* 第二歩:codeを使用してウェブ認証用のaccess_tokenを取得 */ public function getAccessTokenByCode($code) { $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->appid}&secret={$this->appserect}&code={$code}&grant_type=authorization_code"; // exit($url); // $curl = new Curl(); $result = $this->curl->doGet($url); if (!$result) { // $this->curl->getError() $this->msg = "トークンの取得に失敗しました"; return false; } $result = json_decode($result, true); if ($result['errcode']) { $this->msg = $result['errmsg']; return false; } return $result; } // 第三歩:access_tokenを更新(必要な場合) code経由でopenidを取得 $type 0サイレント認証 1ポップアップ認証 public function getUserInfo($code, $type = 0, $lang = 'zh_CN ') { $result = $this->getAccessTokenByCode($code); if (!$result) { return false; } $member = C::t(PT_USER)->getByOpenid($result['openid']); if ($member) { return $member; } else { if ($type) { $url = "https://api.weixin.qq.com/sns/userinfo?access_token={$result['access_token']}&openid={$result['openid']}&lang={$lang}"; // $return = $this->curl->doGet($url); // このAPIは挙動がおかしく、強制的にファイルヘッダーを表示します $return = file_get_contents($url); if (!$return) { $this->msg = 'ユーザー情報の取得に失敗しました'; return false; } $return = json_decode($return, true); if (!$return) { $this->msg = 'ユーザー情報の取得リターンに失敗しました'; return false; } // file_put_contents('ccc.txt',print_r($return,true),FILE_APPEND); $data = array( 'openid' => $return['openid'], 'name' => $return['nickname'], 'sex' => $return['sex'], 'province' => $return['province'], 'city' => $return['city'], 'country' => $return['country'], 'img' => $return['headimgurl'], 'bindtel' => 0, ); } else { $data = array( 'openid' => $result['openid'], 'username' => "WeChatユーザー_" . random(6,1) ); } $name = rand(100000, 1000000000); $e = $name . "@qq.com"; $password = $e; $id = UserAddEdit(0, $data['username'], $password, $e,10,0,"", $msg); if ($id <= 0) { $this->msg = $msg; return false; } C::t(PT_USER)->update($data, $id); $member = C::t(PT_USER)->get($id); return $member; } } /* 公式アカウント セキュリティセンターでIPホワイトリストを設定 公式アカウントのグローバルでユニークなAPI呼び出し資格情報。公式アカウントが各APIを呼び出す際にはaccess_tokenを使用する必要があります。開発者は適切に保存する必要があります。access_tokenの保存には少なくとも512文字のスペースを確保してください。access_tokenの有効期間は現在2時間で、定期的に更新する必要があります。重複して取得すると、前回取得したaccess_tokenが無効になります。 */ public function getAccessToken($type) { $addtime = TIMESTAMP - 7200; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appid}&secret={$this->appserect}"; $row = C::t(PT_WXTOKEN)->getNew($addtime, $type); if ($row) { return $row['access_token']; } else { $result = $this->curl->doGet($url); if (!$result) { $this->msg = "トークンコンテンツを取得できません"; return false; } $result = json_decode($result, true); if (!$result) { $this->msg = "トークンコンテンツの解析に失敗しました"; return false; } if ($result['access_token']) { C::t(PT_WXTOKEN)->addToken($result['access_token'], $type); return $result['access_token']; } else { $this->msg = "トークンの取得に失敗しました"; return false; } } } // JSチケットを取得 公式アカウント設定 - 機能設定 - JSインターフェースセキュアドメインでの設定が必要 public function getJsTicket() { $addtime = TIMESTAMP - 7200; $row = C::t(PT_WXTICKET)->getNew($addtime); if ($row) { return $row['ticket']; } else { $token = $this->getAccessToken(); if (!$token) { return false; } $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$token}&type=jsapi"; $result = $this->curl->doGet($url); if (!$result) { $this->msg = "JSチケットを取得できません"; return false; } $result = json_decode($result, true); if (!$result) { $this->msg = "JSチケットコンテンツの解析に失敗しました"; return false; } if ($result['ticket']) { C::t(PT_WXTICKET)->addTicket($result['ticket']); return $result['ticket']; } else { $this->msg = "JSチケットの取得に失敗しました"; return false; } } } // js sdk チケット署名 現在のウェブページのURL、#およびそれ以降の部分は含まない public function jsSign($data) { // 1.署名対象のすべてのパラメータをフィールド名のASCIIコード順(辞書順)でソートする ksort($data); // 2.URLキー・バリューペアの形式(つまりkey1=value1&key2=value2…)で文字列string1に連結する。元の値を使用し、URLエンコードは行わない $string1 = $this->ToUrlParams($data); // echo "string1:{$string1}<br/>"; // 3.string1をsha1で暗号化する $sign = sha1($string1); // echo "signature:{$sign}<br/>"; return $sign; } // メッセージ内容を取得 public function getMsg() { return $this->msg; } /** * パラメータをURLパラメータ形式にフォーマットする */ public function ToUrlParams($data) { $buff = ""; foreach ($data as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } } ?> // WeChatログイン function wxlogin() { global $_G,$identifier,$config,$wx; if (!$_G['uid']) { if ($_GET['state']) { //コールバック $member = $wx->getUserInfo($_GET['code']); if (!$member) { exit($wx->getMsg()); } if (!function_exists("setloginstatus")) { include_once libfile('function/member'); } // ログイン状態を設定$wx setloginstatus($member, 2592000); checkfollowfeed(); $_G['uid'] = $member['uid']; $_G['member'] = $member; } else { //認証をリクエスト パラメータをエンコード $redirect = urlencode(getProtocol() . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); $wx->getCode($redirect, 'snsapi_base'); } } } function getProtocol() { return is_HTTPS() ? 'https://' : 'http://'; } function is_HTTPS() { if ($_SERVER['HTTPS'] === 1 || $_SERVER['HTTPS'] === 'on' || $_SERVER['SERVER_PORT'] == 443) { return true; } return false; }

2019年4月5日 · 4 分 · MoeJue