WordPressのカスタムパーマリンクのURL末尾の1が消える現象に対処

WordPressで、カスタムパーマリンクを使っていて、以下のようなことを実現しようとしていました。

パーマリンクを使ってURLを作成し、以下のようなURLのページがあったとします。

http://example.com/test/

このページに /test/ ディレクトリ以下に、数字の /1/というURLを付加し、パラメータとして処理をしようとしました。

http://example.com/test/1

上記のようなURLにして、数字の1を取り出して、プログラム内で処理しようとしていました。

しかし、いざ実行してみると・・・

http://example.com/test/1

とアドレスバーに入力すると

http://example.com/test/  

にリダイレクトされてしまうという現象が・・・・

何故?

ちなみに

http://example.com/test/2

とアドレスバーに入力すると、問題なく表示される。

何で2は通るのに1が駄目・・・?

ということで、問題に対処するために、

WordPressのソースコードに

echo $_SERVER[‘REQUEST_URI’];

を処理開始部分から追記していって、URLがどこで変化しているかを調べてみました。

すると、最初の段階では

http://example.com/test/1

と画面上に出力されていました。

それが、どこで変化しているのか・・・

結論としては

/wp-includes/template-loader.php内の

do_action( ‘template_redirect’ );

この処理の後で、

http://example.com/test/1 → http://example.com/test/

にURLが変化していました。

そして、上記の処理(do_action( ‘template_redirect’ );)をコメントアウトしてみたところ、

http://example.com/test/1

きちんと処理されるようになりました。

この処理を飛ばすとサイトの表示に問題が起きるわけでもなく。

というわけで、調査の結果としては以上となりました。

仮想環境venv内でcronを実行する方法

サーバ内での環境構築で、仮想環境を使用してプロジェクトを作成する場合があると思います。

ただし、仮想環境で作成したプログラムは主に仮想環境内で実行しているので、仮想環境の外からcronを実行しようとした場合に動作しない場合があります。

その場合で、cronで仮想環境からプログラムを実行する手順について調べました。

手順としては、シェルスクリプト(.sh)を作成して、シェルスクリプト内でサーバ内のディレクトリを移動し、仮想環境を有効にしてからプログラムを実行。

後に仮想環境から出るという手順で問題なく実行できました。

以下は仮想環境のvenvを使用した例です。

上記のシェルスクリプト(.sh)を作成し、cronで実行することで問題なく実行することができました。

Adsense自動広告の関連コンテンツのクリック数の確認方法

最近Google Adsenseの、自動広告が利用可能になりましたが、自動広告の中で、関連コンテンツの広告があります。

関連コンテンツは、ページの下部に、同ドメインサイトの関連コンテンツを自動で表示してくれる機能で、複数の関連コンテンツと、関連コンテンツに合わせて広告も表示してくれます。

本記事では関連コンテンツの広告のクリック数と、関連コンテンツの広告でない記事のクリック数の確認方法について掲載します。

関連コンテンツの広告のクリック数

adsenseの広告ありの関連コンテンツのクリック数
※クリックで拡大

Adsenseの管理画面で、パフォーマンスレポート→詳細レポート→「広告フォーマット」で確認できます。

要求されたコンテンツの種類→「ネイティブ/関連コンテンツ/広告あり」の項目を見ると、クリック数や収益が確認できます。

広告でない関連コンテンツのクリック数

adsenseの関連コンテンツの表示回数
※クリックで拡大

Adsenseの管理画面で、パフォーマンスレポート→一般的なレポート→アカウント全体の画面で、
「関連コンテンツ」タブをクリックすることで確認が可能です。

MacOSX High SierraでのLibrary not loaded: libmysqlclient.18.dylibへの対処法

Mac OS S High Sieraで、pythonでMySQLのライブラリをインストールして使用していたところ、以下のエラーメッセージが出てしまい対処に困りました。

環境は、
OS:Mac OS S High Siera
MySQLバージョン:5.6
pythonバージョン:3.6.1
です。

ImportError: dlopen(/Library/WebServer/Documents/crawl/scraping/lib/python3.6/site-packages/_mysql.cpython-36m-darwin.so, 2): Library not loaded: libmysqlclient.18.dylib

原因について調べていたのですが、該当のファイルが開けないということで、該当ファイルへのシンボリックリンクを設定することで解決しました。

まず、

find / -name libmysqlclient.18.dylib

で、該当のファイルの存在している場所を調べます。
私の場合は、

/usr/local/mysql-5.6.19-osx10.7-x86_64/lib/libmysqlclient.18.dylib

にありました。

以下のコマンドでシンボリックリンクを設定しました。

sudo ln -s /usr/local/mysql-5.6.19-osx10.7-x86_64/lib/libmysqlclient.18.dylib /usr/local/lib/libmysqlclient.18.dylib

私の場合は、以上の手順で解決しました。

Linuxサーバの場合は、/usr/local/lib/ でなく、 /user/lib/ のパスらしいのですが、MacOSXの場合は、 /user/lib/ のパスがスーパーユーザでも書き込み不可になっていて、 /usr/lobal/lib/がシンボリックの設定箇所になります。

pythonの勉強メモ

最近人気のプログラミング言語の「python」について、勉強をしたことをメモしていっています。

プログラミング言語がphpをこれまでメインに使っていたので、pythonの基本的なことが理解できていないため、個人的なメモとして書いておきます。

変数と型

pythonは変数を宣言時に、明示的に型を宣言する必要がありません。
これはphpと同じですが、変数も変数であるということを表す、phpでいうと $ のような修飾子を変数の前につける必要がありません。

変数は予約語でない場合は変数であると自動的に判断して処理されます。

配列

pythonで配列を定義する場合は、[]を利用します。

array = []
array = [1,3,4,7]

このようにシンプルに定義できます。
phpとの違いとしては、 array()のような定義をする必要がなく、[]だけなのでシンプルです。

配列を参照する場合は

array[1] #上記の配列の場合3になる

のように参照します。これは他の言語の仕様と変わりません。

配列への要素の追加は

array.append(追加する値)

のように行います。

配列の長さは

count = len(array)

で取得できます。

タプル

タプルは配列と似ていますが異なる点は、一旦タプルに値が入ると後で変更ができないのが異なる点です。

tpl = (1,3,4,7)

のように使用します。
配列の[]が()になっています。

辞書(連想配列)

phpでいうところの連想配列は、pythonでは辞書と呼ばれます。

次の様に定義します。

array = {‘apple’:’りんご’, ‘orange’:’みかん’, ‘lemon’:’レモン’}

dict()を使用することで、配列やタプルの集合を辞書に変更することが可能です。

(例)
array = [[apple,りんご][orange,みかん][lemon,レモン]]
array = dict(array)

上記の例の結果、arrayは最初に示した例と同じ辞書になります。

画面出力

print文で画面出力を行えます。

print(出力したい値)

出力したい値は変数でも配列でも問題ありません。

コメント

pythonでのコメントは、
# コメント
を行頭に入れることでコメントをつけることができるのは他の多くの言語と同じです。

複数行コメントを入れるには

“””
コメント
コメント
コメント
“””

”’
コメント
コメント
”’

のように、シングルクオテーションか、ダブルクオテーション3つで行を囲むことで複数行コメントが可能です。

画面出力

画面出力は、print文で行なえます。

print(出力する内容)

文字列の置換

文字列の置換は、以下の記述で行なえます

文字列 = 文字列.replace(“置換元”, “置換先”)

数値のインクリメント

pythonでは、数値のインクリメントは使用できないので

変数+=1
変数-=1

のように記述します。

変数++
変数–

これは使えません。

yield文

yield文は、関数定義内で使用し、指定された値を返します。

そういう意味ではphpの関数内のreturn文と似ていますが、微妙に違いがあるようです。

python版のreturn文に近い存在ですが、関数内に複数のyield文がある場合全てのyieldの値を返します。

また、for文内にyieldが使用されている場合、for文のループが終了するまで値を返し続けます。

for文

for 変数 in 配列
〜〜〜〜〜

配列をfor文でループする場合、上記のように記述します。

ループ文の中で変数を使用したりできます。

または、

for num in range(数値)
 〜〜〜〜〜

とすることで、数値の回数繰り返しを行います。
numは 0 〜 数値-1 の間で処理されます

mysqlの利用

pythonではmysqlのデータベースと接続するためには様々なクライアントがあります。

その中でもポピュラーなものの一つにmysqlclientがあります。

pip install mysqlclient

でインストールすることができます。

IPython

Pythonは、コマンドラインで「python」とタイプすることで、quit()で終了するまでの間、対話型のインタプリタ形式で実行できます。

これをさらに強化したのがIPythonで、IPythonは、Pythonの対話型実行形式でしか使用できないものの、その部分を大幅に強化したものです。

pythonとは別にipythonとしてインストールすることができ、コマンドラインで

ipython

とタイプすることで使用することができます。

通常のpythonの場合

>>

といった形式でコマンドラインに表示されますが、ipythonの場合

In[1]:
In[2]:
In[3]:

といった形式でコマンドライン上に表示されることも特徴があります。

メルカリで本を販売・発送する際のポイントまとめ

メルカリ

自宅で不要になった本をメルカリで売っていたのですが、けっこう売れて便利です。
特に売れ筋の本は、定価に近い価格ですぐ売れたりもします。

ある程度メルカリで本を売ってみたので、メルカリで本を販売する際のポイントをまとめてみました。

1・アプリ「メルカリカウル」が便利

まずは、メルカリのアプリ本体で本を販売するより、派生したアプリ?「メルカリカウル」を使うと便利です。

メルカリカウル

メルカリに登録してけばアプリをダウンロードするとすぐ使えるのですが、メルカリ本家で本を売ろうとすると、が本の名称を入力したり、値段を自分で調べて登録しないといけないので手間がかかるのですが、カウルを使うとバーコードをスキャンするだけで必要な情報が自動で入力される上に、価格も売れ筋の価格を自動で設定してくれるので、価格を調べる手間も省けるので非常に便利です。

基本的にカウルは出品のフェーズで使用して、注文が入った後のやり取りなどはメルカリ本家のアプリでそのままできます。

2・メルカリで本を販売・発送する際の注意点

以下は、メルカリで本を販売・発送する際の注意点です。

2-1・本に合わせた最適な配送方法を選択する

販売する本によって、最適な配送方法を選択しましょう。
一口に本といっても、本の大きさによって、最適な配送方法が異なります。

小さいサイズ(厚さが薄い)本であれば、らくらくメルカリ便のネコポスやゆうゆうメルカリ便のゆうパケットなどが使用できるので送料が200円以内で安くすみます。
厚さが3cm以下なららくらくメルカリ便かゆうゆうメルカリ便がおすすめですが、3cmから3.5cmの間であればクリックポストがおすすめです。
クリックポストは最も送料が安いですが、発送の際の保証がついていない他、発送のラベル印刷を自分でしないといけません。(そのため、プリンタが必要です。)

3.5cmを超える本で5cm以下くらいの厚さの本であれば、らくらくメルカリ便の宅急便コンパクトがおすすですが、送料が380円かかる他、専用の箱(65円)が必要なので、あわせて445円かかるのでおすすめできません。

それ以上の厚さの本であれば、宅急便になるので送料が600円以上かかるので非常に高いです。

手間はかかりますが、本ごとに最適な配送方法を調べて登録しておくと送料が無駄にかからずにすみます。

配送方法を調べるのには、アプリ「MerCalc」が便利です。

送料計算/送料比較アプリ MerCalc

本の厚さとサイズ、重さを入力すると、最適な配送方法を提案してくれます。

配送方法は多くの種類がありややこしいので、慣れないうちは活用すると良いと思います。

2-2・本の状態の表記に注意

メルカリで本を登録する際に必要なのは、本の状態に関する表記です。

本に汚れがあったり書き込みがあったりするのに、状態を「未使用に近い」にしておくと、注文をした人から商品到着後にマイナス評価がつきかけねません。

商品登録前に、本に汚れがないかや、書き込みがないかなどを十分に活用しておきましょう。

本の状態のチェックが手間だと思う場合は、少なくとも登録の際に、「未使用に近い」や「目立った傷や汚れなし」にはしないようにしておきましょう。

本の状態に問題がある場合は、その状態を説明欄にきちんと記入しておくほうがよいです。

この部分はやや手間がかかりますが、この部分で手を抜くと低評価をもらいかねないので、気になる場合はきちんと確認しておきましょう。

2−3・本の発送の際の注意点

最後に、本の発送の際の注意点です。

本は封筒に入れるだけでそのまま送れますが、本を封筒にそのままいれただけでは、水濡れの可能性や、折れ曲がる可能性があります。

そのため、封筒に入れて本を送る場合でも、水濡れ対策に透明なビニールに入れておくか、緩衝材を挟むなどして折れ曲がる対策をしておけばより配送の際のトラブルも発生しにくいです。

封筒で送る場合は、少なくとも水濡れ対策にビニールに入れるのはしておきたいところです。

データベースのバックアップをDropboxへ転送する方法

サイトの運営をしていて考える必要があることは、ウェブサイトのバックアップをどう取るかです。

仮にバックアップを取っていない場合、何らかの問題が起こってサーバ上のデータが消えた時に、取り返しがつかなくなります。

サーバ上のデータが消える原因としては、作業ミス、サーバのハッキング、サーバ会社川野問題など、様々なものがあります。

これらの問題に対処するための方法もまた多様で、サーバ自体を多重化することなどもありますが、基本はバックアップを取ることです。

中でもデータベースは、毎日変化する場合もあるため、こまめにバックアップを取ることが求められます。

バックアップを取る基本は、cronでデータベースのダンプファイルをサーバ内の特定のバックアップフォルダに保存することですが、この場合、サーバ自体が消えてしまったときにバックアップがありません。

そのため、サーバ自体の障害に対応するためには、サーバの外部ストレージにデータを定期的に退避させておくことも重要になりますが、手動でやると手間がかかります。

1つの方法として、Dropboxにバックアップデータを転送する方法があります。

Dropboxは無料である程度の容量までは使用できるため、バックアップを取る方法の1つとして優れています。

ただし、セキュリティ的には100%安全とはいえないので、顧客の個人情報を含む場合の方法としては推奨できません。

手順についてなのですが、Git Hubで、Linux系のOSからDropboxにファイルをアップロードするシェルスクリプト(dropbox_uploader.sh)が公開されているので、それを利用する方法は簡単なのでおすすめです。

具体的な手順としては、Qiitaの以下のページに詳しく掲載されていますので参考にするとよいと思います。

さくらVPSのデータのバックアップに Dropbox を使ってみる

流れとしては、サーバにdropbox_uploader.shをアップロードして実行権限を与え、必要なDropboxへのアクセス情報(トークン情報)を設定してやるとシェルスクリプトが利用可能になるので、あとはcronで実行することでDropboxへ好きなタイミングでアップロードできます。

動的URLはSEO上不利になるか考察

ウェブサイトを構築するときに、動的URLがサイトを構築する場合に必要となる場合があります。

動的URLとは以下のようなURLで、英語ではquery string(クエリストリング)というようです。

http://ドメイン名/ディレクトリ名/product.php?id=◯◯◯

id=◯◯◯の数字の部分によって、表示されるページが変わるといったかんじです。

この動的URLというのは、SEO上不利になるのかというのは昔からしばしば議論されていて、関係あるとか無いとか言われていました。

公式には、Googleは動的URLだろうと静的URLだろうとGoogleは同様にページを扱うということを表明しています。

しかし、私はいろいろなサイトで実験をしてみた結果として、やはり動的URLはSEO上不利と言えるという結論に至りました。

何故動的URLはSEO上不利なのか

何故動的URLはSEO上不利になるのかということを考察すると、Google botが、複数のページを個別ページだと認識してくれないケースがあるからです

具体的にいうと

http://ドメイン名/ディレクトリ名/product.php?id=1
http://ドメイン名/ディレクトリ名/product.php?id=2
http://ドメイン名/ディレクトリ名/product.php?id=3
・・・
・・・
・・・
http://ドメイン名/ディレクトリ名/product.php?id=126

みたいな商品ページが120ページあるページがあったとして、Google botが、それらを個別ページだと判断せず、1つのページしかGoogleの検索結果にインデックスしない場合があります。

この場合、Googleのウェブマスターツールでは、インデックスカバレッジの項目で

Google により、ユーザーがマークしたページとは異なるページが正規ページとして選択されました
(英語で「Google chose different canonical than user」)

と表示されます。

なぜこういう現象が起こるのかは不明なのですが、例えば上記の例だと

http://ドメイン名/ディレクトリ名/product/1.html
http://ドメイン名/ディレクトリ名/product/2.html
http://ドメイン名/ディレクトリ名/product/3.html
・・・
・・・
・・・
http://ドメイン名/ディレクトリ名/product/126.html

のほうが、個別ページだと認識をしてくれやすいようです。

また、

http://ドメイン名/ディレクトリ名/product/1
http://ドメイン名/ディレクトリ名/product/2
http://ドメイン名/ディレクトリ名/product/3
・・・
・・・
・・・
http://ドメイン名/ディレクトリ名/product/126

のほうがおそらく個別にインデックスしてくれる可能性は高いと思います。

仮にインデックスされた場合はページの評価はどちらのURLでも変わらないと思うのですが、動的URLでは全てインデックスされない場合があるということが分かったので、静的URLのほうが有利であるという結論に個人的には至りました。

Google botが、何故個別ページを単一のページと誤認するケースがあるのかは謎ですが、アルゴリズム上そういう事例が発生する場合があるということが分かったので、私も考えを改めました。

動的URLを静的URLとして扱うためには、サーバ側の設定でmod_rewriteを利用したり、あるいはプログラム上の処理で工夫をする必要があります。

Pythonでスクレイピングの勉強メモ

様々なサイトから特定の情報を収集してまとめたサイトを作成しようと思い、Pythonでスクレイピングの勉強をしています。

メモ代わりにやったことをまとめておきます。

やりたいこと

Pythonで複数のウェブサイトから特定の情報を取り出してきてまとめたい。
何故Pythonかというと、PHPでもできるのだろうけど、最近Pythonが人気なのと、勉強も兼ねて。
スクレイピングして取り出したデータをデータベースに保存するまではPythonでやって、表示するサイトはPHP+WordPressでもいいかなと。

ローカル環境でのテスト

まずサイトを立ち上げる前にローカル環境でテストを行っています。

環境
MacOS High Sierra

Pythonのインストール

まずは最新のPython3をインストール

確認したところ、本記事執筆時点でバージョンは3.6.1

仮想環境の作成

以下のコマンドで、仮想環境を作成します。

python3 -m venv scraping

仮想環境を作成してそれ以下でやることで、開発環境でライブラリの依存関係などをプロジェクトごとに制御しやすい。

上の例では「scraping」という仮想環境を作成。

上記で作成した仮想環境に入るには

. scraping/bin/activate

では入れます。

仮想環境を抜けるには

deactivate

で抜けられる。

ライブラリ「Beautiful Soup」のインストール

スクレイピングをするのに便利なライブラリ「Beautiful Soup」をインストールする。
必須ではないが、あると便利

pip install beautifulsoup4

上記のコマンドでインストールを行う。
エラーが出たが、pipのアップグレートを行うことで解決した

pip install –upgrade pip

簡単なスクレイピングのテスト

簡単なスクレイピングのテストを行った。
Beautiful Soupは、それ自体ではローカルにあるファイルしか読み込めないため、urllibというモジュールをインポートして使用し、組み合わせることで外部URLを、URL指定で読み込むことができる。

上記のプログラムでは、抜き出したいHTMLページのURLからa要素を取り出して、URLとテキスト情報を出力している。

pythonのスクレイピングでやりたいこと

特定のウェブサイトのページの、特定テーブルのtd要素を全て取り出してリスト化したい。
そのために色々と試行錯誤をしてみた。

1・Beautiful Soupを使ってみる

上記の例では、スクレイピングしたい対象のページからtd要素のテキストを抜き出して表示するというもの。

結果としては、途中のtd要素までは取得できたものの、取得するページの要素がJavascriptの広告の部分でストップしてしまい、その先の要素を取り出せなかった。

調べてみたところ、そもそも

soup = BeautifulSoup(html, ‘html.parser’)

でhtml要素を取り出して、何故かページの途中までしか正常に取得できていなかった。
原因は不明。

2.lxmlを使ってみる

Beautiful Soulを使ってみて駄目だったので、lxmlというライブラリを利用してスクレイピングをしてみました。

まずは必要なライブラリをインストールして、基本的なプログラムを作成。
上記の例は、URL指定をしてページを取得するというもの。
取得する部分でエラー。

failed to load external entity “ページURL”

よく分からないけどできなかった。

3. Scrapyを使ってみる

スクレイピング用のフレームワーク「Scrapy」を使ってみた。

Scrapyは

pip install scrapy

でインストールできる。

最初に対話モードで実行したところ、最初の時点でいきなりエラー。
一度は実行できたのに、もう一度実行するとエラーに。
意味不明・・・。

と思っていろいろと操作していたら、pythonコマンドから実行するのではなく、コマンドライン上ですぐに実行すると実行できた。

上記の例では、まずはscrapyで対象のURLのページ内容を取得し、
次で、特定のクラス名のテーブル要素の、tdのテキスト要素を取得できた。

ただし、上記の例での問題として、tdの中にspan要素があり、span要素に挟まれたテキスト情報が除外されてしまうという問題が発生した

response.xpath(‘//table[@class=”クラス名”]/tr/td/span[@class=”クラス名”]/text()’).extract()

上記に変えて実行することで、除外されていたspan要素に含まれるテキスト情報を逆に全て出力することができた。

だんだんコツがつかめてきた。

Scrapyがツールとしては一番使えそうなかんじがした(といっても、簡単なプログラムを作成した結果問題が起きなかった)ので、とりあえずはスクレイピングに使うツールとして決定。

以下は、変数「url」に入った相対パスを、現在クローラーがいるページのURLにつなげて絶対パスに変換する記述

response.urljoin(‘url’)

プロジェクトを作成する

scrapyを使用するにあたって、まずはプロジェクトを作成する

scrapy startproject プロジェクト名

これで、プロジェクト名のディレクトリが作成される。

プロジェクトを作成すると、プロジェクト名のディレクトリ以下に、フレームワークのファイルやディレクトリ一式が自動生成される。

プロジェクトを作成後、設定ファイルとして「setting.py」ファイルが作成されるが、
クロール先のサイトに迷惑をかけないように、

DOWNLOAD_DELAY = 1

を追記しておいがほうがよい。
デフォルトのダウンロード間隔は0秒のため、クロール先のサイトに思わぬ迷惑をかけてしまう場合があるので、この設定をしておくことで、ページのダウンロード間隔が1秒になるため、クロール先のサイトに迷惑を少なくできる。

Spiderの作成

Scrapyでは、Spiderと呼ばれるファイルを作成することで、クローラーを実行する。

Spiderは、コマンドラインから以下のコマンドで作成できる。

scrapy genspider Spider名 サイトのドメイン名

上記のコマンドで、プロジェクトのspidersディレクトリ以下に、「Spider名.py」と呼ばれるファイルが作成される。

ファイルを開くと、デフォルトで

def parse(self, response):
pass

という関数が定義されているが、このparseという関数をScrapyは実行するのでこの関数を変更していく。

parseで実行した処理は、yield文を使用することでスクレイピングした値を返していく。

返す形式は、辞書形式でも問題なし、itemクラスを使用しても問題ない。

itemクラスは、プロジェクトを作成時に、「items.py」というファイル内に定義されていて、ファイルにクラスを定義することで使用できる。

yieldで返した値は、Scrapyを実行する際に、外部ファイルに出力することができる他、後述するItem Pipelineを使用することで、データベースへ保存することも可能。

Item Pipelineの活用

ScrapyにはItem Pipelineと呼ばれる機能があり、使用することでデータをチェックしたり、データベースにデータを保存したり、parseの処理で返したItemオブジェクトを利用した処理を行うことが可能。

Pipelineの記述は、プロジェクトフォルダ内の「pipelines.py」に記述する。

pipeline.pyにクラスを定義し、setting.pyに定義をすることで呼び出す。

ITEM_PIPELINES = {
‘プロジェクト名.pipelines.クラス名’ : 300,
‘プロジェクト名.pipelines.クラス名’ : 800,

上記の例の300や800といった記述は優先度で、数が小さいほど優先して処理される。
0〜1000までの間で定義され、優先度が高い順から定義されたクラスが処理される。

ここで、yieldで返されたitemオブジェクトのチェックを行ったり、データベースに保存する処理を行える。

pipeline.py内の関数 process_item内に、pipeline実行時に処理をする記述を行う。

WordPressをSSL移行でアクセス数が大幅に減少・・・原因を考察

最近のGoogleからの推奨で、ウェブサイトの全体SSL化が推奨されていますね。

私が運営している複数のサイトも、SSLに対応するため、複数のサイトをSSLに対応しました。

SSL移行の手順

手順としては以下の通りです。

1. サイトをHTTPSで見れる設定にして、記述を諸々変更する
2・ 301リダイレクトでHTTPへのアクセスはHTTPSへ飛ばす
3・ ウェブマスターツールでHTTPSのサイトを新しく登録し、Google AnalyticsのサイトのURL設定を変更する

といった形で、複数のサイト(10サイト程度)をほぼ同時期にHTTPS化しました

SSL化する方法としては、Cloudflareの無料SSLを使っています。

結果

結果としてですが、複数のサイト(10サイト程度)で、アクセス数の増減が発生しました。

SSL化してすぐに発生したわけではなく、1週間か2週間程度経ってから発生しました。
(それまでは問題なかったのにです。)

サイトのアクセス数の減少度合いはサイトによってばらつきがあり、最も大きく減少したサイトは、アクセス数が6割程度減少しました。

少ないサイトでは2割程度の減少で、サイトによってはアクセス数がほぼ変動なしのサイトや、むしろ増加したサイトも見られました。
(大幅に増加したサイトはなく、微増といったかんじです)

何故アクセス数が減少したかの考察

アクセス数が減少した理由についていろいろと調査してみましたが、まず、ウェブマスターツールを調べてみたところ、サイト全体の平均検索順位の低下はそこまで顕著には見られませんでした。

それにも関わらずアクセス数が減少幅が大きいサイトで6割も減少したのは、別の理由がありました。

原因としては、HTTPS移行後の特定のURLがインデックスに登録されなくなったことにありました

ウェブマスターツールで調べてみたところ、以前はインデックスされて上位に表示されていた複数のページが

「Google により、ユーザーがマークしたページとは異なるページが正規ページとして選択されました」という結果でインデックスから削除されていることが確認されました。

それらのページがランディングページとしてサイトに流入していたアクセスがごっそり消えてしまったわけです

上記のエラーは、HTTPのURLとHTTPSのURLが混在しているため、HTTPSのほうを非表示にしているといった内容ではなく、何故か移行後の特定のURLがそれまでは単一のURLとみなされていたのが重複URLをみなされてインデックスから除外されてしまうということが発生してしまったわけです。

これには正直困りました。

なぜなら、そのサイトでも、特定のページは問題なく移行できているものもあるのに、特定のURL(パーマリンク設定のURL)のぶんだけ移行できなくなってしまったからです。

設定に不備がなかったからサイトのページを何度も確認してみましたが、Canonical設定の不備や記述の不備も見当たらず、困り果ててしまいました。

そもそも、サイトやページによって何故こうもばらつきがあるのかも理解できませんでした。

HTTP→HTTPSへの完全な移行には一ヶ月ほどかかるそうなので時間がかかるのであれば仕方がないですが、もし回復しなかった場合、致命的な結果ということになります。

結論:サイト全体のHTTPS化は一概に推奨はできない

HTTPSの通信は、ネット通販で個人情報を入力するサイトなど、サイトによってはなくてはならない必須の技術です。

しかし、サイト全体のHTTP→HTTPS化は、移行に伴う検索順位の低下のリスクが伴うことが分かりました。

移行手順に不備があった可能性も考えられますが、それがGoogleの管理コンソールにどういった理由かも表示されず、ただ一方的に順位の低下やインデックスからの削除のみ、結果として受け取らないといけないのは、Google側の不備としかいいようがない気がします。

HTTPS化はGoogleから推奨はされているものの、検索順位のアップなど、メリットが明確に受け取れるわけではないので、どうしても必要という場合以外は見送ったほうが賢明な判断だと思いました。

kusanagiのphp.iniの設定変更方法

利用しているサーバはConohaのKusanagiで、Nginx+php7の環境。

phpでフォームを作った際に、PHPの「max_input vars」の設定に引っかかって、変数が投稿できなくなってしまった。

調べてみると、現状の設定が

max_input vars 1000

になっていて、これを

max_input vars 3000

あたりに変更したい。

nginxは、.htaccessが使えないので、php.iniで設定を変更するが、どのファイルを変更したらいいのか分かりにくい。

そのときは、phpinfo()で出力したファイルで、php.iniの設定ファイルの場所が確認できるので、場所を確認する

私の環境の場合には

/etx/php7.d/php.ini

を変更すればよかった。

上記のphp.iniを開き

max_input vars 1000

max_input vars 3000

に変更

その後、設定を反映させるためにphpを再起動

kusanagi php7

私の環境はphp7なので、上記のコマンドでphpを再起動して反映できる。

現在の自分の環境を確認するには、

kusanagi status

のコマンドが便利な他、phpの設定の確認には phpinfo() を利用するとよいだろう。

Nginx+php7へのWordPress移行で苦労した点まとめ

PHP7+Nginx

サイト運営に利用していたサーバを、サーバの運営に利用していたPleskの値上がりを受けて別のサーバへ移行しました。

サーバの環境もけっこう代わりました。

移行前の環境
php5+Apache

移行後の環境
php7+Nginx

すんなりサーバが移行できたわけでなくて、いろいろとトラブルも発生したので発生した問題点と、解決方法について備忘録として書いておきます。

1.サーバを移行しようと思った理由

これまで使用していたサーバの月額費用が、Pleskのライセンス費用で値上がりしたと、いってみればそれだけの理由です。
試算してみると、Plesk抜きのサーバへ移行すると月額2000円〜最大で3000円ほど(年額換算で3万円ほど)節約できる試算になったのでこのタイミングで移行することにしました。

2,移行したサーバ会社

ConohaのVPSに移行しました。

Conohaを決めた理由としては

  • サーバに最新技術が導入されていてサイトの動作速度向上が期待できる
  • Pleskは使えないが、Kusanagiコマンドで簡単にサイト設定を行うことができる
  • 費用面でサーバのメモリを少なくすれば月額費用はかなり少なくてすむ

という点になります。

2.移行プロセス

カスタムパーマリンクが機能しない

まず、サーバ管理のソフトウェアをApacheからNginxに変更しました。

理由としては、速いから? よく分かりませんがそうしました。

そしてPHPのバージョンを7にしてみたのですが、これはうまく行かず、理由としては、WordPressのカスタムパーマリンクが上手く機能しなかったから。

URL/〜〜〜/〜〜〜/

上記のようなWordPress上で設定していたURL設定が機能せず、Not Foundとなる。
この解決方法がわからなかったので、別の方法を考えました。
(理由としてはNginxの設定だったのですが、最初は分かりませんでした)

Apache + HHVMを試してみる

結局サーバのNginxではだめだったので、HHVMでサーバを変更してみることにしました。

HHVMというのはPHPのバージョンの1つのようなものなのですが、NginxではなくApacheで動作します。
kusanagiだとワンボタンでサービスを変更できるので、変更してみたところ、問題なくサイトが機能した・・・ように見えました。

訪れる謎の高負荷と、サーバダウン

HHVM+Apacheは、HHVMのキャッシュに機能で動作が非常に高速で、サーバ移行前と比べると動作が高速化してめでたしめだたし・・・・かと思いました

が、数時間おきにサーバに謎の高負荷がかかりサーバダウンするという現象が起きました。

とりあえず応急処置としてこまめにHHVMの再起動設定

調べてみたところ、ConohaのKusanagiのHHVMは不安定でときどきダウンすることがあるということでした。

応急処置として、cron設定で1分ごとにHHVMを再起動するように設定しました。
これにより、仮にサーバがダウンしても長時間そのままダウンし続けるという自体は避けることができます。

原因はよく分からないのですが、とりあえず同様の現象の方はいたようで、またあくまで応急処置で、数時間に一度、数分程度サーバがダウンしてしまうということ自体が解消されたわけではなく、さすがにその状況でサーバを運営し続けることは品質面で問題といえます。

そこで、別の方法を検討することにしました。

すると、Nginxに切り替えると安定するということでした。

Nginx+PHP7に再度挑戦

最初にいったんやろうとしてあきらめたNginx+PHP7への移行に再度挑戦してみることにしました。

Conohaのサービスでは、サーバをイメージ保存しておいて、そのコピーのサーバを簡単に作成できるので、HHVMのサーバは残した状態で、コピーしたサーバを作成し、Nginxの設定に変更してテストを行いました。

こういうことがコントロールパネルから簡単にできるのも、Conohaの優れている点です。

カスタムパーマリンクの対応

まず、カスタムパーマリンクが動作しない点については、Nginxは.htaccessが使えないのでNginxの設定ファイルに記述しないといけないということでした。

Nginxの設定ファイルは、nginx.confというファイルに設定されているのですが、このファイルに正規表現を使って様々な記述がされていたので、この設定をサイトごとに設定しました。

この作業は少し手間がかかる作業でしたが、完了することで、無事パーマリンクが機能するようになりました。

PHP7で動作しないファイルの修正

次に、以前のサーバがPHP5で動かしていたので、PHP7になることで動作しないファイルが大量に出現したので、これらのエラーファイルを順に修正していきました。

エラー箇所の特定は、Nginxのエラーログファイルを見ながらエラー箇所を特定し、修正してきました。

これらは運営しているサイトの数が多かったのでかなりの作業量が必要になり、なかなか大変な作業だったのですが、HHVMにしたときに数時間おきに少しの間サーバがダウンするのはサービス品質に対して影響が大きいだろうということでやむをえず行いました。

PHP5の記述とPHP7では、特にデータベース回りの記述が変更になっている箇所が多かったので、修正箇所は多岐に渡りました。

また、WordPressのプラグインも、PHP7に対応していないプラグインは削除したり、ファイルの修正で対応できるものは対応するということが必要になりました。

サーバの移行完了

これらの作業を終えることで、無事Apache+PHP5からNginx+PHP7への移行が完了しました。

つまづいた点としては、

  • .htaccessが使えないのでパーマリンク設定をnginx.confに記述しなければならない
  • PHP5の記述が一部動作しないのでエラーが起こる点はPHP7で動作するように修正しなければならない

という主に2点になります。

思った以上に移行作業は時間はかかりましたが、結果的にサーバのランニングコストを下げることができ、サイトもNginx+PHP7になったことで高速化したように見えるのは良い点ではないかと思います。

まだサーバが移行したばかりなので予期せぬトラブルはあるかもしれませんが、しばらく様子見したいと思います。

phpでファイルをinclude時に謎の空白行が入る問題を解決

  • 2018年5月10日 6:46 PM
  • php

phpのファイルで、特定のファイルをincludeして読み込んだ場合に、謎の空白行が上に1行入る問題がありました。

発生した問題

phpファイルのヘッダの上に謎の空白行が1行表示される

原因の究明方法

まずはchromeのデベロッパーツールでソースコードを調べたが、ソースコード上には何の問題も見られない。
phpファイルのプログラムの行を削除して調べていたところ、特定のphpファイルをincludeした際に改行が入っていた。
該当のphpファイルを調査したが、問題ないソースコードであるように見受けられ、不要な出力や改行、全角文字なども見当たらなかった。

解決策

該当の問題となっていたphpファイルを新規作成して作り直し、同様のコードをコピーペーストして同様の内容とした。
作り直したファイルをアップロードしたところ問題は解消した。

つまり、もともとのファイルを作成した際に、文字コードや改行コードの微妙な違いがあったようである。

詳しい原因は分からないが、作成した時に使っていたエディタや環境と、現在使っている環境(phpstorm)が異なっていたために、微妙な差があって発生していた問題かもしれない。

メルカリをはじめて使ってみた感想

メルカリ

これまでネットショップで売買をするのにはもっぱらヤフオクを使っていたのだが、新しいものも使ってみないと分からないということで、使ってみました。

以下、メルカリを使ってみた感想です。

メルカリの良い点

1.登録が簡単

サイトに登録をするのがまず簡単です。
本人確認やらややこしい作業が必要かなと予想していたのですが、かなり簡単に登録することができました。
口座情報などは後から設定が可能です。

2.出品が簡単

出品するのが簡単です。
使ってみたのは、本を出品する「メルカリカウル」というサービスがあってそれを使ってみたのですが、本の出品がバーコードをスマホで読み取ると登録でき、値段も売れ筋の価格が自動で登録されるというもの。
本1冊の登録に1分もかからないという手軽さに驚きました。

3.配送が簡単

配送も提携しているヤマトなどの配送所やコンビニを使うと簡単です。
スマホから生成したバーコードを読み取ることで送り主と宛先の情報が自動で登録されます。
手書きで住所や氏名、電話番号を書く必要が無いことには驚きました。

欠点

1・手数料を取られる

欠点としては、手数料を取られることがあげられます。
手数料は売上の10%取られるので、1万円の商品を売り上げたら1000円は手数料で取られてしまいます。
このため、高額の商品であればせっかく売れても手数料である程度取られてしまうのがネックです。
自分で経営しているネットショップであれば手数料をとられずにすむので、仮にそちらで売ることができるのであれば、そちらのほうが利益率は高いですね。

総合的な感想

総合的な感想としては、「とにかく簡単」ということは何よりもメリットとしてあげれます。
めんどくさい部分をシステム化・自動化して、利用者にとって取引が楽にできる形態がつくりあげられていると思います。

EC-CUBE3インストール時のステップ4:データベース接続エラーを解決

EC-CUBE3のインストールをローカル環境で試していたところ、ステップ4のインストール時のデータベース設定でエラーが出た。

データベースに接続できませんでした。 || An exception occured in driver: SQLSTATE[HY000] [2002] No such file or directory

データベースはMySQLを使用していて、データベースとユーザは作成済みだったがエラー。

原因はよくわからなかったが、以下の方法で解決した。

ホスト名の部分を

localhost

から

127.0.0.1

に変更

これで通るようになった。

原因はよくわからないが、おそらくローカル開発環境の設定上の問題であろうと思われる。

ウェブ制作の市場規模について

ホームページ制作会社でかつて働いていたものとして、ウェブ制作の規模というものについて調べてみました。

1.Web制作の市場規模

正確な数字の把握は難しいですが、2017年のWebインテグレーションの市場規模は

1270億円

ということでした。

毎年10%程度の市場が増加していっているということです。

ただし、上記はどういった方法で集計されているのかは不明です。
クラウドソーシングなどもあると思うので、実際はもっと大きい可能性もあると思います。

2.都道府県別分布

都道府県別にどのくらいホームページ制作会社が分布しているのでしょうか。

以下のサイトによると、ほとんどの仕事が東京に集中しているのが分かります。

全国のWebデザイナーの求人分布 – 求人数が色分け地図でわかる「ココある!仕事」

地方のほうでは求人数が10とかなのに対して東京都が5000とかになっていて、500倍くらいの仕事の数に差があるということが分かります。

都会の中でも東京が圧倒的で、2位の大阪の10倍くらいの求人が存在していますね・・・。

上記はWebデザイナーについてでしたが、Webエンジニアにしても同様でした。

世の中にある様々な仕事で地方と都会はどれも差がありますが、IT系の仕事は特に都会と地方の格差が大きくなっている印象があります。

1の結果により、ウェブ業界全体では1200億ほどの市場規模はあるそうですが、東京に仕事がほとんどの仕事を集中していることを考えると、地方の県では市場規模が2億程度しかない?という感じではないかと思われます。

県全体で2億円ということは、それをその県内にいる複数の事業者が奪い合うことになるので、トップクラスの事業者でも数千万円の売上といったかんじでないのではないかと思います。

MacのOSをHigh Sierraにアップデートしたらphpが動作しなくなったので対処メモ

MacのOSアップデートが来ていたので、Hight Sierraにアップデートしたら、ローカルの開発環境のApacheのphpプログラムが動作しなくなってしまった。

具体的にいうとソースコードが表示されてプログラムが動作していない。

原因を調べてみると、とりあえずMacのOSを最新版にアップデートすると、Apacheの設定ファイルであるhttp.confが最新版に置き換わってしまうので、設定内容を確認する必要がある。

ちなみに、Macのhttpd.confは /etc/apache2/httpd.conf にあるが、OSアップデート時にアップデート前の設定ファイルが httpd.conf.pre-update にバックアップされている。

diff /etc/apache2/httpd.conf /etc/apache2/httpd.conf.pre-update

上記のコマンドで差分を確認できる。

差分を確認していると、結論から言うと MacのOSをHigh Sierraにアップデートすると、phpの推奨環境は php7 になっていて、php5は推奨されないようだ。

High Sierraでは、デフォルトの設定が

LoadModule php5_module libexec/apache2/libphp5.so

だったのが、

LoadModule php5_module libexec/apache2/libphp7.so

になっている。

無理にphp5を動かすことも可能だろうが、おとなしく推奨環境のphp-7に対応してみることにした。

対応としては、一旦phpをアンインストールしてから、最新版のphp7をインストールする。

homebrewを使っているので、まずは brew-update で homebrewを最新版にアップデートしてから、php5.6をアンインストールしてphp7をインストールすることにした。

ざっくりというと下記のようなかんじ。

brew update //homebrewを最新版にアップデート
brew unlink php56 //php5.6をアンインストール
brew install php71 //php7.1をインストール
php -v //バージョン確認

これでphpのバージョンが7にできていることを確認できた。

これで httpd.confの諸々の設定を変更してみたのだが、相変わらず動作しない。

Apacheのエラーログをあさってみたところ

#LoadModule unixd_module libexec/apache2/mod_unixd.so

LoadModule unixd_module libexec/apache2/mod_unixd.so

この読み込みができていなくてエラーが出ているようだったので、コメントを外すことで動作するようになった。

しかし、これでようやくApacheのサーバは動作するようになったのだが、phpのプログラムがエラーで動作しなくなった。

調べてみると、php7系では、mysql系の関数がオブジェクト指向の使い方が推奨されていてmysql系の関数が使用できなくなっているようなので、諸々修正する必要があるようだ。

とりあえず、データベース接続関係以外のプログラムは問題なく動作していたので、該当箇所だけ修正しないといけないのだが、けっこう多くの修正が必要となってしまうが、この対応はまた時間があるときにする予定。

MacでAirPodsの音が出なくなった場合の対処法

Macで、Apple製のイヤホンAirpodsをbluetooth接続したときに、音が出なくなりました。

対処法として試した見たことを書いておきます。

まず、Macの右上のツールバーで、Bluetoothのメニューから、表示されているAirpodsのメニューから「サウンド環境設定を開く」を選択します。

設定画面1

設定画面が開いたら、下にある「主音量」のメニューから音量が入っているかどうかを確認します。
また、「消音」にチェックがもし入っている場合は外します。

上記の設定を確認してみてください。
私の場合は、主音量が一番低くなっていたので、音量を調整することで治りました。

この手順でなおらない場合は、一旦blutoothの設定をオフにして再度オンにしてAirpodsを設定したり、Macを一旦再起動してみたりすると治る場合もあるようです。

phpにmycrypt拡張を追加する

phpmyadminを使っていたところ、画面の下に「mycrypt拡張がない」と表示が出たので、調べて入れてみた。

yumでepelリポジトリからインストール

yum install –enablerepo=epel php-mcrypt

エラーが表示された(以下訳)

Resolving Dependencies
依存性を解決しています

There are unfinished transactions remaining. You might consider running yum-complete-transaction first to finish them.
終了していないトランザクションが残っています。
完全なyumのトランザクションを最初から完了まで実行することを検討してください。

The program yum-complete-transaction is found in the yum-utils package.
yumの完全なトランザクションプログラムはyumのユーティリティのパッケージに見つかりました。

–> Running transaction check
トランザクションの実行をチェックしています。

—> Package php-mcrypt.x86_64 0:5.3.3-5.el6 will be installed
php-mcrypt.x86_64 0:5.3.3-5.el6のパッケージがインストールされます。

–> Processing Dependency: php(zend-abi) = 20090626 for package: php-mcrypt-5.3.3-5.el6.x86_64
パッケージのためのphp(zend-abi) = 20090626は依存性があります。

–> Processing Dependency: php(api) = 20090626 for package: php-mcrypt-5.3.3-5.el6.x86_64
パッケージのためのphp(abi) = 20090626は依存性があります。

–> Finished Dependency Resolution
依存性の解決が終了しました。

Error: Package: php-mcrypt-5.3.3-5.el6.x86_64 (epel)
Requires: php(api) = 20090626
Installed: php-common-5.4.20-1.el6.remi.x86_64 (@remi)
php(api) = 20100412-x86-64
Available: php-common-5.3.3-49.el6.x86_64 (base)
php(api) = 20090626

エラー:
パッケージのためにphp(api) = 20090626が必要です。
php-common-5.4.20-1.el6.remi.x86_64 (@remi)がインストールされています。
php-common-5.3.3-49.el6.x86_64 (base)が利用可能です。

You could try using –skip-broken to work around the problem
–skip-brokenをつけることでこの問題に対処できるかもしれません

You could try running: rpm -Va –nofiles –nodigest
rpm -Va –nofiles –nodigestを実行してみてください

訳してみたが、訳しきれないし、結局意味もよく分からない。

ただいえることは、依存性関係でエラーが起きているということである。

エラーメッセージの中の

Installed: php-common-5.4.20-1.el6.remi.x86_64 (@remi)

に注目すると、php-commonがremiで入っているということなので、remiリポジトリからインストールしてみた

yum install –enablerepo=remi php-mcrypt

すると今度は問題なく実行できた。

よく意味は分からないが、結果的にインストールできたので良しとする・・・。

ダイジェスト認証を使うメリットと使用方法

特定のサイトや、公開していない特定のディレクトリに閲覧制限をかけるときによく使われるのが基本認証(basic認証)です。

ただし、基本の認証方法の問題点として、パスワードが平文で送信されてしまうというものがあります。

このため、公衆無線LANなど暗号化されていない場合、かつ非SSLのようなサイトで基本認証のみに頼るのはセキュリティ的に問題があるといえます。

この問題点を解消しているのがダイジェスト認証です。
認証をかけているサイトにアクセスした場合、IDとパスワードを入力するとアクセスすることができるのは同じですが、パスワードが暗号化されて送信されるため、基本認証よりもセキュリティ的に安全性は高いといえます。

ただし、問題点としては基本認証に比べると新しいためか一部の古いブラウザなどに対応していないことです。
ただし非対応ブラウザがIE5以前とか、古いガラケーなどということで、多くの人が通常使用しているブラウザには概ね対応しているということなので、開発用に使用するにあたってはそれほど大きな問題とは言えないと思います。
なお、対応していないブラウザでアクセスした場合はエラーを返してアクセスはできないようです。

また、サーバによっては使用できない場合もあるそうなので、その場合はApacheであればhttpd.confの設定を一行変更することで使用できるようになります。

LoadModule auth_digest_module modules/mod_auth_digest.so

上記記述(最初からある)がコメントアウトされていなければ問題なく使用できます。

設定方法に関してですが、基本認証と同じように .htaccessに記述する方法で設定できます。

ほとんど基本認証と変わりませんね。

.htpasswdの記述方法に関しては、以下のように書きます。

ユーザ名:認証名:暗号化したパスワードフレーズ

例えば、以下の例であれば

user:auth:password

パスワードの部分には、上記の文字列を(user:auth:も含めて)そのままMD5暗号化したものが入ります。

上記の例であれば

user:auth:4481f9057c05e4c3c85c52d9d7dee0f0

が入るわけです。

設定方法は以上になります。

基本認証よりはセキュリティ的に強度は高いので、問題がなければ基本認証よりはダイジェスト認証を使うので良いのではないかと思います。

phpmyadmin設置時に画面が真っ白になるエラー(500)に対処

使用していたサーバに最新のphpmyadmin(この記事を書いている時点で4.7.4)を設置したところ、画面が真っ白になるエラーに見舞われた。

chromeの場合は画面が真っ白になって
「このページは動作していません(500エラー)」
といった内容で、SafariとFirefoxではただ真っ白になるだけ。

初期設定がいるのかと思い、調べてみたところphpmyadminはファイルをアップロードするだけでよく特に初期設定は不要ということ。

とりあえずphpmyadminは、プログラムはphpファイルなので、index.phpに

ini_set( ‘display_errors’, 1 );

を頭に追加してやり、エラー表示をさせたところ、読み込んでいる特定のphpファイルで

phpmyadmin Parse error: syntax error, unexpected なんちゃらなんちゃら

といったエラーが表示された。
構文エラーが起こっているということ。

調べてみると、最新のphpmyadmin(4.7.4)には、動作するのに php5.5〜7.1 と MySQLの5.5が必要となるということ。

結論をいうと、サーバのphpのバージョンが最新版に対応していませんでした。

phpmyadminのダウンロードサイトで旧バージョンも提供されていたので旧バージョンをインストールしなおすことで解決しました。

CentosでデータベースのバックアップをDropboxに転送する

CentOSでデータベースのバックアップをDropboxに転送する方法についての解説です。

データベースの二重バックアップの必要性

CentOSのサーバでデータベースを使ったサイトを運用している場合に、まずやる設定がデーターベースのバックアップを取って(mysqldump)、同じサーバのバックアップ用のディレクトリに保存するということをやる人は多いと思います。

しかし、この方法だともしサーバ自体に障害が発生して使えなくなったり、あやまって全部消してしまった場合などにデータの復旧ができなくなります。

この場合に、サイトを運用しているサーバ内に保存し、かつ外部のストレージにも保存しておくと、もし何らかの障害がサーバに発生した場合でもデータの復旧が可能になります。

外部ストレージに何を使うか

保存する外部ストレージには最近ではいろいろありますが、安価で有名なストレージはDropboxがあります。
無料の場合は容量に制限がありますが、それでも2GBまでであれば保存可能なので、ある程度までのデータであれば保存可能です。

欠点としては、セキュリティ上の問題は考えられますので、個人情報など重要な情報を含むDBの場合はもっと安全な方法を取るべきです。

Dropboxへのデータの保存手順

Dropboxへのデータへの保存手順にはいくつか方法があります。

まず、サーバにDropboxをインストールして、直接サーバ内のDropboxの保存ディレクトリに保存するという方法もあります。
この方法は分かりやすいですが、調べた所によると問題もいろいろあるようなので今回はパスしました。

他には、Wordpressの場合であればプラグインを使うことでも簡単に設定可能ですが、サイトの数が増えていくると都度プラグインを入れて設定する必要があるので多少手間がかかります

別の方法としては、サーバ内のデータを指定してDropboxにアップロードする方法です。
今回はこの方法を採用しました。

分かりやすいサイトとしては、以下のサイトの説明をほぼそのまま参考にしました。

第54回「SORACOM応用編!ラズベリーパイからDropboxへファイルをアップロード(1)Dropbox-Uploader」 | Device Plus – デバプラ

詳しくは上記のサイトに手順が書いてあるので詳細は割愛。

やり方としては至極単純で、Dropbox Uploaderという便利なシェルスクリプトがあるので、これをダウンロードしてサーバ内に設置して実行権限をつけるだけ。

最初にこのシェルスクリプトを実行するときにDropboxのアクセストークンについて入力しないといけないので、その設定をDropboxのサイトにログインして取得しないといけません。
必要な作業としてはそれだけです。

あとは、そのシェルスクリプトを実行して、引数にファイル元とアップロード先のディレクトリとファイル名を指定してDropboxにアップロードするだけです。

実行してアップロードが確認できれば、それをcronにセットしてやると問題なくDropboxへの転送ができました。

問題点

この方法の問題点としては、まずはDropboxのセキュリティ上の不安というのはあるかもしれないと思うので、個人情報を含むデータなどの場合は注意する必要があります。

それ以外では、Dropboxの容量が知らない間にいっぱいになっていてアップできていなかったというトラブルが起きる可能性はあるので、データのアップロードと保存が失敗した場合にメールでアラートが届くようになるとなお信頼性が高くなります。

phpでGoogleでの検索ランキングを取得する

PHPのプログラムで特定のサイトURLとキーワードからGoogleでの検索順位を取得し、結果を返すプログラムを作りたいと思いました。

理由としては、運営しているサイトの検索順位の日時変動を手動でチェックして記録するというのは手間がかかる作業だからです。

プログラムで実行でき、さらにcronで自動実行し、結果をデータベースに保存するということができれば楽になります。
そういうツールもあるのですが、何かと制限があったり、融通はきかないので。

まず、プログラムで検索順位を取得する方法についてですが、考えられる方法として、Googleの検索フォームにポストで変数を投げて、結果をスクレイピングするというものですが、これは規約によりやるとまずい場合があるということでやめました。
実行回数が多かったり検知されるとIPアドレスをブロックされるということがあるみたいです。
実際にやってないので分かりませんが・・・。

もう1つの方法として、Google Custom Search APIを使用するというものです。
こちらは公式に許可されている方法なので問題はないのですが、無料の場合は1日100クエリまでということで制限が入るようです。

それでこの方法を試してみたところ、一応目的に近いものはできたので、詳細は省略しますが、ざっくりとその過程と、この方法の現状での問題点を書いていこうと思います。

1. Google Custom SearchのAPI keyを取得する

Google Custom SearchのAPIを使用するにはAPI KEYが必要となるので取得します。
方法はネットを探すと出て来る思うのでここでは省略します。

2. カスタム検索エンジンIDを取得する

プログラムの中で使用するカスタム検索エンジンの検索エンジンIDを取得します。
カスタム検索エンジンIDは、カスタム検索エンジンを作成してから、詳細の画面で「検索エンジンID」というボタンを押すと表示されます。
※ 画面はときどき変わってしまいますが、探すと詳細画面のどこかで取得できると思います。

なお、カスタム検索エンジンを作成の際にはどのサイトで使用するかのサイト名を入力する必要があるのですが、作成後に詳細画面から「基本」タブの「検索するサイト」の項目で「追加したサイトを重視して、ウェブ全体を検索する」に設定を変更することで、

3. プログラムを作成する

1.2.のAPI KEYとカスタム検索エンジンIDを作成できればあとは、目的のサイトURLとキーワードから検索結果を取得できます。

プログラムの詳細としては、カスタム検索エンジンに、検索キーワードと、その他のパラメータを引数にしてクエリを作成して引き渡すことで、JSON形式でデータが返ってくるので、それをデコードして解析します。
こう書くとややこしそうですが、プログラムとしてはそれほど複雑ではありません。
以下のサイトが参考になりました。

Google Custom Search APIを使って検索結果のURLを取得する【PHP】 – autofocus onfocus

あとは、それを目的に応じてプログラムをチューニングすると完成です。

私の場合は、複数のサイトとキーワードとサイトで調べたいので、それをテーブルに保存して引っ張り出してきてキーワードとサイトごとに実行して順位を返す。
帰ってきた順位と日付をDBに保存というところまではできました。

問題点

これで一応目的としたものについてはできたのですが問題もあります。

1.無料でのクエリ数の制限

まずは先にもあげたように、無料の場合は1日100クエリまでしか実行できないというもの。
このため、サイトの数やキーワードが増えてくると無料では対応しきれませんので、調べたい数を絞る必要があります。
増やそうと思った場合、1日に追加で1000クエリあたり$5がかかるようです。

2.検索順位が微妙に本家サイトと違う?

あと1つの問題点は、この方法で得られた検索結果と順位が微妙に本家のものと違うということです。
これは理由がよく分からないので、検索結果の厳密さを必要とする場合にこの方法はあまり推奨できないのですが、大まかな目安とする程度であれば問題なく使用できます。
これは、何故検索結果が本家と異なるのかがよく分かっていないので、今後もし原因が分かれば追記しようと思います。

phpでYoutubeの短縮URLを埋め込み用URLに変換して出力する方法

PHPで、Youtubeの短縮URLを、埋め込み用URLに変換して出力する方法についての解説です。

Youtubeの短縮用URLとは、

youtubeの短縮URL

上記のようなURLで、Youtubeの動画を共有ボタンを押すと表示されて、それをSNSやブログに投稿すると、Youtubeの動画が埋め込まれた状態で出力されます。

これは、例えばそれぞれのブログエンジンや、SNSなどが上記の短縮URLを埋め込み用のコードに変換して出力する仕様になっているのでそのようになっています。

そのため、例えばPHPのファイルで、上記のYoutubeの短縮用URLを受け取ってそのまま出力すると、そのまま短縮用のURLが出力されるだけで、埋め込まれた状態で出力されません。

これをそのまま埋め込み用の動画として出力したい場合は、埋め込み用のURLに変換して出力する必要があり、そのための関数を作ってやると出力することができます。

埋め込み用のコード

埋め込み用のコードについてですが、基本的にiframeを使って、先程の短縮URLを一部変形させて埋め込んでやればそのまま出力できるので、それほどややこしい処理は必要ありません。

以下は私の方で作成した関数例です。
関数呼出し時に関数に短縮用URLを渡し、埋め込み用のiframeにしたURLを返却します。
ifameの横幅はデフォルトが560にいていますが、引数として渡すことで大きさを変える事が可能です。

ゲーム市場についての考察

最近のゲーム市場と、今後のゲーム市場についての考察です。

1・日本のゲーム市場について

2016年の日本のゲーム市場は全体が1兆4000億円程度の市場規模。
オンラインプラットフォーム(PC、スマホだが、おそらくほぼスマホ)がここ5年くらいで大きく成長しているが、スマートフォンの普及に伴って
成長率はここ最近は伸びが低調になってきている。
家庭用ソフト、家庭用ハードの合算の合計は10年間で約半分になっていて、ここから増える見込みはあまり考えられない。
一方で、スマートフォンのゲーム市場もある程度天井に近い状態になっている。
スマートフォンゲームの市場規模は大きいが、これもここから増える見込みも今のところ大きく考えられない。
(つまり、競争は激しくなっていく)

現在の日本の市場規模でいうと、家庭用ソフト:スマホアプリ、PCゲーム=2:8。
ユーザ数でいうと家庭用ゲーム:PCゲーム:スマホゲーム=20:10:35 くらいである。

2・世界のゲーム市場について

世界のゲーム市場は10兆円近く。
日本全体と比べると約10倍近い市場規模がある。
日本はゲーム市場として大きいが、中国に抜かれている。(とはいえ、それほど差が大きくない)

ゲームの事情は国によって大きく異なっている。

北米

北米市場は、専用ゲーム機が人気で全体の約半数を占めている。
つまり、PS4やXboxOneや任天堂のゲーム機である。
スマートフォンの市場は全体の15%程度しかない。
ゲーム市場の中でPCゲーム市場が25%程度ある。

中国

中国は全体の7割近くがPCゲーム市場である。
これは政府が海外の専用機のゲームの販売を禁止していたことに起因すうr.
スマートフォンゲームの市場は全体の2割程度である。
家庭用専用機の市場は1割程度しかない。

3・世界のゲーム市場の動向

ゲーム市場を考える上での考え方としての主なポイントは「ゲームをプレイされるハードの種類」「国別・地域別」でどのように市場の大きさが推移していくかということである。

まず、ハードの種類は主に「スマートフォン」「家庭用ゲーム専用機」「PC」という区分に大きく分けることができ、この3つのカテゴリーはそれぞれ推移こそしてもなくなることはほとんど考えられない。
ただ、その割合はある程度変化しつつ推移していくことが予想される。
世界のゲーム市場は今度も成長することが予想されるが、主に成長する市場はスマートフォン市場である。

また、現在主要となっている地域の勢力が今後どのように推移していくかということに注目される。
この15年くらいで起きた変化で一番大きなものは「中国」という国の市場が大きくなり世界最大となったことだろうが、今後どうなるのかということを考えると、まずは多くの人口を抱えているインドだろう。
それ以外にも、人口を多く抱えているアジアがどうなっていくかというところに注目が集まる。
アジアは世界全体の60%の人口が住んでいるが、現在も全体の50%程度の市場規模を持っている。
ただし、これはほとんどが中国、日本、そして韓国で構成されていて(あと少し台湾、インド)それらの構成がどう変化していくか。

2017年のスマホゲームの注目ゲーム

2017年の半分が終わりましたが、下半期にリリースされるスマホゲーム(iOS/Android)で、注目のゲームについてまとめてみました。

テラバトル2(夏)

ミストウォーカーの発売したパルズゲーム「テラバトル」の続編に当たる作品。

予想DL数:150万

テラバトル2 公式トレイラー

ドラゴンクエストライバルズ(未定)

人気ゲーム「ドラゴンクエスト」をモチーフにした本格的なカードゲーム。
ゲームシステムは「ハースストーン」や「シャドウバース」を彷彿とさせる。

公式サイト

予想DL数:1000万

『ドラゴンクエストライバルズ』ティザー映像

どうぶつの森

任天堂とDeNAが共同で開発している人気ゲーム「どうぶつの森」のスマホアプリ。
2017年度後半リリースの予定。

予想DL数:1000万

ファイナルファンタジー エクスプローラーズ フォース

ファイナルファンタジーシリーズのスマートフォンアプリ。
3DSで発売された作品の系列で、ジャンルはハンティングアクション。

予想DL数:200万

公式サイト

アークザラッド

プレイステーションの人気ゲーム「アークザラッド」の続編アプリ。
どういったゲームシステムなのかなど、詳細は現段階では不明。

予想DL数:200万

妖怪ウォッチ

3DSでの人気作品「妖怪ウォッチ」のスマートフォンアプリ。
ゲーム内容は3DSの妖怪ウォッチと近い。

予想DL数:500万

【プレイ映像】『妖怪ウォッチforスマートフォン』

2018年発売の専用ゲームの注目ゲームと販売本数予想

2018年に専用ゲーム機発売予定での個人的に注目のゲームと、販売本数の予想についてまとめました。

モンスターハンターワールド(上半期・PS4)

PS4でのモンスターハンターの最新作。
大幅に進化したリアリティのあるグラフィックが最大の特徴。

予想販売本数: 日本:150万本 海外:150万本

ディシディアファイナルファンタジー NT(上半期・PS4)

ディシディアファイナルファンタジーのPS4での最新作。

予想販売本数: 日本:50万本 海外:100万本

シェンムー3(下半期・PS4)

クラウドファンディングで制作が決定したシェンムーの最新作。

予想販売本数: 日本:20万本 海外:100万本

エースコンバット7(未定:PS4)

PS4で発売予定のエースコンバットの最新作。

予想販売本数: 日本:20万本 海外:100万本

2017年の専用ゲーム機での注目ゲームと売上予想

2017年も残り半年となりましたが、2017年に専用ゲーム機での、個人的に注目の発売ゲームスケジュールについてまとめています。

7月

ファイナルファンタジー12 ゾディアックエイジ(7/13/PS4)

ファイナルファンタジー12のPS4でのリマスター作品。
FF12のHDリマスターでありながら、ジョブシステムなど新要素が追加されている。

売上予想:日本40〜50万本 世界100万本くらい?

スプラトゥーン2(7/21/Switch)

人気を博したスプラトゥーンの続編に当たる作品。
売上予想:日本 100万本 世界:250万本 合計350万本

ドラゴンクエスト11(7/29/PS4・3DS)

国民的RPGドラゴンクエストのナンバリングタイトルに当たる作品。

売上予想:日本 250万本 世界:150万本 合計 350万本

8月

モンスターハンターダブルクロス Switch Ver(8/25/Switch)

ニンテンドースイッチでのモンスターハンターダブルクロス。
高精細な画質でダブルクロスをプレイできる。

売上予想:日本:30万本

NEW みんなのGOLF(8/31/PS4)

PS4で発売するみんなのGOLF。
売上予想:日本:80万本 世界:100万本

9月

アンチャーテッド 古代神の秘宝(9/14/PS4)

PS4で発売されるアンチャーテッドシリーズの作品。
売上予想:日本:10万本 世界:400万本

ファイアーエムブレム無双(9/28/Switch)

Switchで発売されるファイアーエムブレムの無双系の作品。
売上予想:日本:5万本 世界:50万本

英雄伝説 閃の軌跡Ⅲ(9/28/PS4)

英雄伝説、閃の軌跡の続編シリーズ。
売上予想:日本:15万本 海外:15万本

10月

スーパーマリオオデッセイ(10/27/Switch)

スーパーマリオのオープンワールド系のゲーム。
売上予想:日本:100万本 海外:500万本

11月

二ノ国Ⅱ レヴァナントキングダム(11/10・PS4/PC)

レベル5の二ノ国の続編に当たる作品。
スタジオジブリとのコラボではないが、元ジブリの百瀬義行氏とのコラボ作品。
作曲は久石譲氏。

売上予想: 日本:20万本 海外:100万本

ポケットモンスター ウルトラサン・ウルトラムーン(11/17/3DS)

ポケットモンスターの3DSの新作。
売上予想: 日本:300万本 海外:500万本

発売日未定

グランツーリスモ SPORT(秋頃・PS4)

PS4で発売されるグランツーリスモシリーズの新作。
売上予想: 日本:80万本 海外:600万本

ゼノブレイド2(冬/Switch)

Switchでのゼノブレイドの新作。
売上予想: 日本:20万本 海外:80万本

iPhone,iPadでスイッチコントロールが解除できなくなった場合の対処法

iPhone、iPadには「スイッチコントロール」という機能があり、使用することで、特定の入力を繰り返してくれたり、あるいは入力の補助に使えたりしてくれてます。

ただし、何かバグのようなものがあるようで、通常であればホームボタンをトリプルクリックすることで解除できるのですが、解除できなくなる場合があります。

その場合、通常の操作に戻れなくなり、例えば電源を長押しにして一旦再起動をかけようと思っても「電源オフにする場合は横にスライド」のところで詰まってしまい再起動できなくなってしまいます。

その場合の対処法についてなのですが、「ホームボタン+電源ボタンを長押し」で強制再起動をかけることができ、この方法で再起動をかけることで直すことができました。

Yahooショップの在庫なし商品を一括で非表示にする方法

Yahooショップの在庫なし商品を一括で非表示にする方法についてです。

Yahooショップは、ユーザ側在庫がない商品を商品一覧でチェックを入れることで非表示にすることができるのですが、チェックを入れない場合在庫なし商品でもずっと商品一覧に表示されたままになってしまうので、あまり見栄えが良い状態にはなりません。

また、その状態で管理画面から一括で商品を非表示にすることができないので、基本的には一つ一つ商品を非表示にしていくしかない、数が多い場合は対応が大変になります。

そこで、CSVを使うことで一括で非表示にする方法について調べてみました。

1.在庫なし商品一覧をダウンロードする

ストアエディタの「在庫管理」から、左下のほうにある「在庫切れの商品データ」の「ダウンロード」でデータをダウンロードします。
在庫なし商品のcsvファイルがダウンロードできます。
また、もう1つの在庫がある商品も含めての商品データのダウンロード(在庫の商品データのダウンロード)も合わせて行います。

2.商品データをダウンロードする

ストアエディタの「商品管理」から、左下の商品データの「ダウンロード」で商品データをダウンロードします。
このときに、事前に上にある「CSVダウンロード項目の選択」で、必要なもの以外のチェックを外します。
必須項目以外は全てチェックを外して下のほうにある「display/ページ公開」にチェックを入れて保存します。
CSVダウンロードには時間がかかる場合があるので、その場合は一度ダウンロードをして、少し時間が立ってからもう一度実行するとダウンロードできます。

3.CSVファイルを1つのエクセルシートに開く

ダウンロードした3つCSVファイル(全在庫商品データ、在庫切れ商品データ、全商品データ)をエクセルファイルで3つのシートにそれぞれ開きます。
この場合、普通にエクセルファイルを開くと先頭の0が消えたりとおかしくなるので、データインポートを行います。
エクセルの「データ」→「外部データの取り込み」→「テキストファイルのインポート」からインポートします。
データのファイル形式:区切り記号付き、元のファイルで適切なのを選んで「次へ」→区切り文字が「コンマ」のみにチェックで「次へ」→列のデータ形式「文字列」で、データのプレビューで全選択(一番右までスクロールしてシフト+クリック)で「完了」→既存のワークシートで「OK」

なお、エクセルがない場合はGoogleスプレッドシートでもできると思いますが、ここではエクセルで調べていますので、おそらく同様のことはスプレッドシートでもできると思います。

4.CSVファイルの編集

CSVファイルの中で、商品データが入ったシートを編集します。

まずは、「全商品の在庫」が入っているシートを編集します。
ここで、「quantity」の列をフィルタで「0」、「」(空)のセルのみをフィルタして、フィルタされた行を全て削除します。
これで、全商品の在庫のシートでなく、在庫がある商品のみのシートになります。

次に、全商品のシートを編集します。
は、「display」の列の右の列に、次の数式を入れます。

これがどういう式かというと、商品コードを比較して、在庫なしシートに商品コードが存在した商品の場合は0にして、存在しなかった場合は1にしています。
つまり、在庫なし商品に商品があった=0、なかった=1で値が入ります。
この数式を一番下までコピーします。
(一番下までコピーするのは数式セルを選択して、右下の小さい四角をダブルクリック)

次に、さらにその右側の列に次の数式を入れます。

これはどういう式かというと、在庫のある商品の場合は1を表示し、それ以外は0を表示しています。
この数式を一番下までコピーします。

最後に、その右の列に次の数式を入れます。

これがどういう式かというと、もともと0の場合は0(もともと非表示の商品は非表示のまま)で、
そうでない場合(1で表示商品の場合)で、在庫がある場合も1で(在庫がある商品場合は1のまま)
そうでない場合で、在庫がない商品の場合は0にしています。
この数式を一番下までコピーします。

こうすることで、もともと0:非表示、1:表示

なのですが、現在表示になっている商品で、在庫なしの非表示にしたい商品は0になります。
何故こんな複雑な方法をとっているかというと、同じ商品コードでも複数の商品がある場合があり、ある商品コードが在庫が0でも、同じ商品コードで在庫がある場合があり、その場合は表示にする必要があるからです。
これで、もともと表示している商品の中から、本当に在庫がない商品は0になります。

5.CSVファイルの作成

上記のシートが完成したら、まずCSVを編集する専用のソフトで、最初にダウンロードして、もともとの全商品のデータファイルを開きます。
そして、displayの列を、4の手順で最後に作成した列で置き換えます。
その後、CSVを保存します。
このときに項目ごとの引用符などは最初にダウンロードした状態の設定と合わせて保存します。
何故CSVを編集できるソフトで保存するかというと、エクセルがCSVを作成する専用のソフトではなくデータが変更されていると困るからです・・・。

6.CSVファイルのアップロード

最後にCSVファイルのアップロードを行います。
アップロードはYahooストアエディタの「商品管理」から行います。

アップロードする前に「バックアップ」で全データのバックアップを念のためとっておきます。(これも商品数によっては時間がかかります)
また、今回更新するデータは商品データなので「商品データ」→「ダウンロード」でもバックアップをとっておくとよいです。
バックアップをすることで、もしアップロードでデータの更新に失敗した場合でもあとで巻き戻せます。

「商品データ」→「アップロード」から「項目指定」にチェックを入れ、「ファイルを選択」で、5の手順で編集したCSVファイルを選択し、アップロードします。

アップロードが完了したら「反映管理」からサイト全体に反映を行います。
反映には15分ほど時間がかかるので、サイトを確認して正しく更新ができていれば作業完了で、万が一失敗した場合にはバックアップからデータを巻き戻すことも可能です。

ホーム

フィード
リンク集

ページの上部に戻る