リロードするとFatal error: Call to undefined **となる問題

【問題】リロード時にUndefined Errorとなる

APCのオペコードキャッシュを有効化した時、サーバーを立ち上げると最初は表示されるものの、リロードすると「Fatal error: Call to undefined **」となってしまう。

apc.iniの以下の部分を「apc.enable_opcode_cache=1」とすると上記の現象になる。

; This can be set to enable the APC opcode cache
; WARNING: don't set this option if another opcode cache is enabled
apc.enable_opcode_cache=0

環境は、nginx + PHP 5.4.28(php-fpm) + APC(3.1.15dev beta)です。

【原因】APCのエラー

エラー回避の方法を調べていくと、どうやらAPCの特定バージョンで起きる不具合だったよう。詳細な再現条件は調べてないので不明ですが、APC(3.1.15dev beta)では上記不具合が起きていました。

サーバー立ち上げ時にオペコードキャッシュがAPCによって作成され、リロード時は生成されたキーを元にオペコードキャッシュを呼ぼうとするが、そこでこけてしまいFatal Errorとなるようです。

▼参照 PHP :: Bug #61219 :: method not found on 2nd request Upgrade to PHP 5.4 from PHP 5.3 - undefined method SWIFT_License::DecodeKey()

【解決策】Zend OPCacheを導入する

パッチを当てれば直るらしいのですが、オペコードのキャッシュはZend OPCacheにすることにしました。ちなみに、Zend OPCacheはPHP5.5から導入されたものですが、PHP5.4でも問題なく使えます。

理由は、ざっくり以下の2点です。

APCはすでに開発が止まっている ・Zend OPCacheのほうがパフォーマンスが良い(らしい)

Zend OPCache+APCの構成で解決

ただし、Zend OPCacheはユーザーデータのキャッシュには対応していないため、Zend OPCacheだけではWordPressのオブジェクトキャッシュが使えません。

そのため、APCはオペコードキャッシュには使わずにZend OPCache+APCという構成にすることにしました。

もしパッチを当てて直したいという人は、こちらのパッチを参照してみてください。

[amazonjs asin=“4844362526” locale=“JP” title=“WordPress 高速化&スマート運用必携ガイド”]

iframeのURLを親ウィンドウのフォームから変更するJavascript

jQueryなしのプレーンなJavascriptを使って、iframeのURLを変更するTips。

<form name="targetForm">
  <input type="text" name="query" />
  <input type="button" value="送信" onclick="SendSubmit()"/>
</form>

<iframe name="searchFrame" style="width:100%;height:650px" sandbox="allow-forms"></iframe>
<script type="text/javascript">

function SendSubmit(){
  var query = document.targetForm.elements['query'];
  var targetURL = "http://example.com/?s=";
  document.searchFrame.location.href = targetURL + query.value;
}
</script>

ちなみにGoogleFlickrなどはクリックジャッキング対策のためiframe内からの呼び出しを禁止しているそうです。

このクリックジャッキングとは、簡単に言うとiframe内に表示されたサイトにJSやCSSを使った悪意のある「なりすましボタン」を設置することを指すそうで、HTTPレスポンスヘッダにX-Frame-Optionsを追加することで対策することができます。 ▼参考 クリックジャッキングって?

[amazonjs asin=“4873115736” locale=“JP” title=“JavaScript 第6版”]

Bing Search APIで画像取得する簡易チュートリアル(PHP編)

1.登録&アカウントキーの取得

Microsoft Azure Marketplace」から、プランを選ぶ。無料で使う場合は、5,000トランザクション/月。

マイ アカウントから「プライマリ アカウント キー」を取得。

2.Bing Search APIのサンプルコード(PHP

エラー処理などしてないですが、こんな感じで使えます。

ドキュメントは、クイックスタート(英語)パラメーターなどの一覧(英語)があります。


/**
* BingSeachAPIで画像を取得するサンプルコード
*
* @param string $keyword 検索ワード
* @return object 
*/

function search_bing($keyword) {
  //取得したアカウントキー
  $accountKey = 'aaaaaaaaaaabbbbbbbbbbbbbb';

  //エンドポイントとパラメーターなどをセット
  //画像検索以外の場合は$serviceOpを変更
  $query = urlencode("'{$keyword}'");
  $rootUri = 'https://api.datamarket.azure.com/Bing/Search';
  $serviceOp = "Image";
  $endpoint = "$rootUri/$serviceOp?\$format=json&Query=$query&ImageFilters='Aspect:Wide'";

  //ストリームコンテキストを作成
  $auth = base64_encode("$accountKey:$accountKey");
  $data = array(
    'http' => array(
    'request_fulluri' => true,
    'ignore_errors' => true,
    'header' => "Authorization: Basic $auth")
  );
  $context = stream_context_create($data);

  //とりあえず、file_get_contents()でjsonを取得
  $response = file_get_contents($endpoint, 0, $context);
  $response = json_decode($response);

  return $response;
}

3.画像検索で使うパラメーターImageFilter

「ImageFilters=‘Aspect:Wide'」みたいに指定できます。

Size:Smallサイズ小の画像を取得
Size:Mediumサイズ中の画像を取得
Size:Largeサイズ大の画像を取得
Size:Height:{Height}{Height}(数字)に指定されたサイズの画像を取得
Size:Width:{Width}{Width}(数字)に指定されたサイズの画像を取得
Aspect:Square正方形の画像を取得
Aspect:Wide横長の画像を取得
Aspect:Tall縦長の画像を取得
Color:Colorカラー画像を取得
Color:Monochromeモノクロ画像を取得
Style:Photo写真を取得
Style:Graphicsイラスト、グラフィックを取得
Face:Face顔?の画像を取得
Face:Portrait肩から上が写った画像を取得
Face:Otherその他の人物写真?を取得

4. 注意点:ImageFilterのエラー

シンプルなAPIなので特に気をつける点はないのですが、ImageFilterに複数パラメーターをセットするとエラーになるのには注意です。

公式ドキュメントには、「ImageFilters=‘Aspect:Wide+Size:Large'」のように複数セットできそうな記述があるのですが、実際には以下の様なエラーになります。

Parameter: ImageFilters has an invalid pattern of characters

フォーラムにも質問が書いてあるのですがどうやら仕様のようです。2012年1月に下記の質問が投げられ、それから進捗はないようなので今後の対応は望み薄な気がします。

▼参考:フォーラムでの質問 Azure Bing Search API - Image search with multiple image filters

[amazonjs asin=“4861007623” locale=“JP” title=“アフィリエイターのための Web APIプログラミング入門”]

TwentyFifteenを独自テンプレートにカスタマイズする方法

シンプルなWordPressのテンプレートを探していたところ、意外と「TwentyFifteen」が良さそうだったのでカスタマイズしてみました。

0. ファイル構成

TwentyFourteenに比べるとファイルも少なくなっているので良いですね。

ちゃんと見てないですが、style.css内のメディアクエリもブレークポイントが少なくなっているようでカスタマイズしやすそうです。

content*.phpといったファイルは、WordPressループなどを含むコンテンツの表示用のファイル。

また、inc/以下のファイルはfunctions.phpで読み込まれるカスタマイズ用のファイルです。

404.php404 テンプレート
archive.phpアーカイブ
author-bio.php著者情報
comments.php コメント
content-link.phpリンクポストフォーマット用
content-none.phpコンテンツがない時用
content-page.php固定ページ用
content-search.php検索結果
content.phpメインとなるコンテンツ表示
footer.php フッター
functions.phpテーマのための関数
header.php ヘッダー
image.php画像添付テンプレート
inc/back-compat.phpWordPress4.1未満用
inc/custom-header.phpカスタムヘッダー用
inc/customizer.phpテーマカスタマイザー
inc/template-tags.phpテンプレートタグ
index.phpメインインデックスのテンプレート
page.php 固定ページテンプレート
search.php 検索結果
sidebar.phpサイドバー
single.php 単一記事の投稿
style.cssスタイルシート
rtl.cssRTL スタイルシート

2. functions.phpから不要なコードを消す

WordPress4.1未満用の互換性確保のために back-compat.php を読み込む部分。 今回は不要なので削除。

/**
 * Twenty Fifteen only works in WordPress 4.1 or later.
 */
if ( version_compare( $GLOBALS['wp_version'], '4.1-alpha', '<' ) ) {
  require get_template_directory() . '/inc/back-compat.php';
}

twentyfifteen_setup()内の不要な設定を削除。

言語ファイルの設定。一部英語化してしまうけれど、あとで修正するので削除。

/*
* Make theme available for translation.
* Translations can be filed in the /languages/ directory.
* If you're building a theme based on twentyfifteen, use a find and replace
* to change 'twentyfifteen' to the name of your theme in all the template files
*/
load_theme_textdomain( 'twentyfifteen', get_template_directory() . '/languages' );

ポストフォーマットの登録。使わない人は削除。

/*
 * Enable support for Post Formats.
 *
 * See: https://codex.wordpress.org/Post_Formats
 */
add_theme_support( 'post-formats', array(
  'aside', 'image', 'video', 'quote', 'link', 'gallery', 'status', 'audio', 'chat'
) );

テーマを管理画面からカスタマイズする用(カスタムヘッダーなど)不要なので削除。

$color_scheme  = twentyfifteen_get_color_scheme();
$default_color = trim( $color_scheme[0], '#' );

// Setup the WordPress core custom background feature.
add_theme_support( 'custom-background', apply_filters( 'twentyfifteen_custom_background_args', array(
  'default-color'      => $default_color,
  'default-attachment' => 'fixed',
) ) );

custom-header.php、customizer.phpは不要なので削除。

/**
 * Implement the Custom Header feature.
 *
 * @since Twenty Fifteen 1.0
 */
require get_template_directory() . '/inc/custom-header.php';

/**
 * Customizer additions.
 *
 * @since Twenty Fifteen 1.0
 */
require get_template_directory() . '/inc/customizer.php';

3. 不要なファイルを消す

functions.phpを編集した後に、下記のファイルを削除。

rtl.css
back-compat.php
custom-header.php
customizer.php
content-link.php

4. カスタマイズ

To be Updated…

[amazonjs asin=“B00UR988KS” locale=“JP” title=“本格ビジネスサイトを作りながら学ぶ WordPressの教科書 Ver.4.x対応版”]

AWSにscpでファイル転送したらPermission deniedされてググった

AWSWordpressをインストールできたので今回はEC2サーバーにファイル転送をするところまで。

少しつまずいたので、その解決策も含めてご紹介します。

EC2にssh接続をしてみる

まずはダウンロードしたpemファイルを任意のディレクトリにコピー。

$ cp blog_sample.pem ~/.ssh/blog_sample.pem

ssh接続をしてみます。

ssh -i {.pemファイル} ec2-user@{Public DNS}」で接続できます。

Public DNSAWSのコンソールの以下の赤枠のところで確認できます。

$ ssh -i ~/.ssh/blog_sample.pem ec2-user@ec2-54-199-188-193.ap-northeast-1.compute.amazonaws.com

The authenticity of host 'ec2-54-199-188-193.ap-northeast-1.compute.amazonaws.com (54.199.188.193)' can't be established.
RSA key fingerprint is 1b:10:ae:e5:9e:60:ad:01:83:32:ca:ef:97:0a:68:93.
Are you sure you want to continue connecting (yes/no)?

このような画面が出るので、yesと入力してEnterします。 すると以下の様なエラーが出てしまいました。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/yuichi.iwayama/.ssh/blog_sample.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /Users/yuichi.iwayama/.ssh/blog_sample.pem
Permission denied (publickey).

pemファイル(Private Key Files)のアクセス権限がオープンすぎると怒られてしまいました。

なので、chmodでアクセス権限を変更して再度ssh接続します。

$ chmod 400 ~/.ssh/blog_sample.pem
$ ssh -i ~/.ssh/blog_sample.pem ec2-user@ec2-54-199-188-193.ap-northeast-1.compute.amazonaws.com

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2013.09-release-notes/

↑のような表示が出てssh接続ができました。

ssh接続できることが確認できたので、一旦接続を切ります。

$ exit

sshのconfigに設定を追加 毎回長いコマンドを打つのは面倒なので、設定をします。

sudo vi ~/.ssh/config

viで以下のように追記します。

Host blog_sample
  User ec2-user
  HostName ec2-54-199-188-193.ap-northeast-1.compute.amazonaws.com
  Port 22
  IdentityFile ~/.ssh/blog_sample.pem

これで上書き保存すると、

ssh blog_sample

とするだけでssh接続ができるようになります。

問題:EC2にscpでファイル転送するとpermission deniedとなる

ここまでできたところで、ファイル転送をしてみます。 Macの場合は、ターミナルからscpコマンドでファイル転送をすることができます。

AWSの公式マニュアルどおりにターミナルからscpでファイル転送をしてみます。 インストールしたWordPressのthemes以下に新しいテーマ(sampleディレクトリ)を転送してみましょう。

$ sudo scp -i ~/.ssh/blog_sample.pem -r sample ec2-user@ec2-54-199-188-193.ap-northeast-1.compute.amazonaws.com:/var/www/vhosts/i-fefef5f8/wp-content/themes

scp: /var/www/vhosts/i-fefef5f8/wp-content/themes/sample: Permission denied

* i-fefef5f8はインスタンスID

Permission deniedととなり転送ができない。

解決策:chmodで権限を変更する

ただの権限のエラーだったので、chmodコマンドですべてのユーザーがアクセスできるように権限を変更してexit。

$ ssh blog_sample
$ cd /var/www/vhosts/
$ sudo chmod -R 777 i-fefef5f8
$ exit

これでもう一度ファイル転送をしてみると。

$ sudo scp -i ~/.ssh/blog_sample.pem -r sample ec2-user@ec2-54-199-188-193.ap-northeast-1.compute.amazonaws.com:/var/www/vhosts/i-fefef5f8/wp-content/themes
sample.txt   100%   0   0.0KB/s   00:00 

転送できた!

[amazonjs asin=“B00UWCYRZK” locale=“JP” title=“Amazon Web Services パターン別構築・運用ガイド  一番大切な知識と技術が身につく”]

さくらのレンタルサーバーにSSH接続とファイル転送してみる

実は、「さくらのレンタルサーバー」にはSSH接続ができるんです。ファイル転送するのもいいですが、ターミナルを使いたい場合もありますよね。

「さくらのVPS」にSSH接続するのとは、少し違うの注意が必要です。

さくらのレンタルサーバーSSH接続してみる

FTPサーバ名     : sample-account.sakura.ne.jp
FTPアカウント   : sample-account
FTP初期フォルダ : www
サーバパスワード: samplepassword

契約時にメールで送られてきたサーバ名、アカウント(FTPアカウントと同一)とサーバパスワードを使ってSSH接続してみます。

別に難しいことはなく、「ssh アカウント@サーバ名」で接続できます。

ただし、レンタルサーバーなのでroot接続ができないという点には注意です。

$ssh sample-account@sample-account.sakura.ne.jp
    The authenticity of host 'sample-account.sakura.ne.jp (11.222.33.44)' can't be established.
    RSA key fingerprint is dd:86:2e:b3:ee:0e:79:b1:7f:ae:86:85:b6:f9:5b:04.

    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'sample-account.sakura.ne.jp' (RSA) to the list of known hosts.

    sample-account@sample-account.sakura.ne.jp's password: 
    
    Last login: Fri Apr 25 16:37:17 2014 from kd124213.ppp-bb.dion.ne.jp
    FreeBSD 9.1-RELEASE-p9 (SAKURA16) #0: Wed Jan  8 21:05:11 JST 2014

    Welcome to FreeBSD!
$ exit

秘密鍵と公開鍵をローカルで作成

次に公開鍵と秘密鍵を作り、レンタルサーバーに転送します。

これをすることで、ssh接続時にパスワードを入力しなくて済むようになります。

$ cd ~/.ssh
$ ssh-keygen
// id_rsaとid_rsa.pubができていることを確認
$ ls
  id_rsa id_rsa.pub
// レンタルサーバーに転送する
// この時、id_rsa.pubを/home/sample-account/.sshにauthorized_keys2とリネームして転送
$ scp id_rsa.pub sample-account@sample-account.sakura.ne.jp:/home/sample-account/.ssh/authorized_keys2
// ssh接続してみる
ssh sample-account@sample-account.sakura.ne.jp

sshのconfigファイルを編集

次にsshのconfigファイルを編集して、さらに楽にssh接続できるようにします。

vi ~/.ssh/config

以下の内容を書き加えます。Hostの部分は任意の文字なので、sampleとしてもOKです。

Host sample-acount
  User sample-acount
  HostName sample-acount.sakura.ne.jp
  Port 22
  IdentityFile ~/.ssh/id_rsa

上書き保存したら「ssh [設定したHOST名]」で接続できます。

ssh sample-account

今回はこれで接続できれば完了です。

さくらのレンタルサーバーにファイル転送する

さっき使ったscpコマンドを使って、ファイル転送をします。ひとつずつファイル転送するのは面倒なので、ディレクトリごと回帰的に転送してしまいましょう。

sudo scp -i ~/ssh/id_rsa -r [転送元] [アカウント名]@[ホスト名]:[転送先]

というコマンドになります。

今回は、WordPressのwpex-prontoというテーマを転送することにします。

$ sudo scp -i ~/.ssh/id_rsa -r ~/vagrant/wordpress/wordpress/wp-content/themes/wpex-pronto sample-account@sample-account.sakura.ne.jp:/home/sample-account/www/wp/wp-content/themes

これで転送が完了です。

あとは、bashrcなどにエイリアスや関数を設定すればさらに便利になります。

[amazonjs asin=“4883379426” locale=“JP” title=“小さな会社の新米サーバー/インフラ担当者のためのLinuxの常識”]

WordPressでパーマリンク変更をした時のリダイレクト設定

WordPressパーマリンク設定を変更したら、リダイレクトの設定をサーバー側(もしくはプラグイン)でする必要があります。

今回は、nginxでリダイレクト設定をする時の

目的:旧URLから新URLに301リダイレクトする

nginxのrewriteを使って301リダイレクト(恒久的なリダイレクト)をしてみます。

「数字ベース」から「カスタム構造」に変更した時などには、忘れずにリダイレクトしておきたいです。

記事ページに関しては、

(旧) http://web-tsukuru.com/archives/123
(新) http://web-tsukuru.com/123

また、タグを設定していたので、

(旧) http://web-tsukuru.com/archives/tag/tag-name
(新) http://web-tsukuru.com/tag-name

とリダイレクトするように設定します。

解決策:default.confにrewriteルールを追記

nginxの設定ファイルがある/etc/nginx/conf.dにあるdefault.conf(*1)に設定を追記します。

serverブロック内にlocationディレクティブを追記し、その中にrewriteルールを設定することでリダイレクトできます。

*変更する設定ファイルはサーバーによって変更してください。

vi /etc/nginx/conf.d/default.conf

Proxy Cacheを使っているので、ポート80のほうのserverブロックに以下のように追記します。

location ~ /archives/ {
    rewrite ^/archives/(.*)$ /$1 permanent;
}

locationで/archives/以下をリダイレクトするように設定。リライトルールは以下のように記述します。

rewrite リダイレクトするディレクト リダイレクト先 リダイレクトの種類;

今回、リダイレクトするディレクトリはarchives/%post_id%とarchives/tag/%tag%なので、^/archives/(.*)$とする。

()$で囲った部分は、$1のように変数として使用できます。リダイレクト先は今回ドメイン直下にしたので、/$1というように変数を使って指定します。

具体的には、/archives/123にアクセスがきた場合は$1変数には「123」がはいり、/123にリダイレクトされます。

追記したらnginxを再起動すればリダイレクトの設定は完了です。

service nginx restart

[amazonjs asin=“4844362526” locale=“JP” title=“WordPress 高速化&スマート運用必携ガイド”]