プログラミング備忘録(PHP、JavaScript、WordPress等)

WEB制作を行っている、とある個人事業主のプログラミングに関する技術メモをアウトプットしていきます。

HTTP→HTTPSのリダイレクトがうまくいかなかった場合の対処法(メモ書き)

まず最初にお断りしておきたいのは、あくまでも自身のケースであり、適合しない場合もあります。
また、.htaccessを触るのは自己責任でお願いいたします。

やりたいこと

WordPressブログのSSL化に伴い、http://xxxx.xxx/からhttps://xxxx.xxx/にリダイレクトしたい。
なお、サーバーはエックスサーバー。

ネットでよく見る解決策

.htaccessに下記を入れる方法です。「wordpress http https リダイレクト」なんかで検索するとまさに下記対応が殆どを占めています。


```

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

```

実際に試すと、このコードだと何も変化がなく、リダイレクトされません。
場所を変えたり色々試してはみるものの、どうしようもない状況です。

更に様々なキーワードで検索していると、%{HTTPS}ではなく、%{SERVER_PORT}を使っている例があったので試してみました。

```

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

```

サーバーポートが80(非SSL)なら、リダイレクトするという条件ですね。
この方法で試すと、バッチリリダイレクトされるようになりました。

もし同じような現象で悩んでいる方がいましたらご参考になれば嬉しいです。

備忘録でした。

Yeomanの導入手順備忘(MacOS)

一つ作りたいWEBアプリがあり、どの言語で作ろうか考えていましたが、SPA(Single Page Application)で作ってみようと思っています。
Gruntなどにも触れておきたいというのがあったので、Yeomanで環境構築をしてみます。

Yeomanとはいわゆるスキャフォールディングツールですね。

「The web's scaffolding tool for modern webapps」

昔はビルドツールはmakeで手書きで書いてやっていましたから、Gruntなどの自動ビルドツールには大変感謝しています。一回GruntやGulpなどのビルドツールの使い方を覚えてしまえば劇的に不毛な作業からサヨナラできそうですね。

詳しい解説は割愛しますが、ここではインストール時のメモを記載します。

※HomeBrewとnpm、node.jsが入っている前提(バージョンを最新にしておく)
なにやら、nodebrewを使ったほうがいいという記事をあとから見つけたので、そちらで試してもいいかもしれません。
YEOMANをインストールしよう!(だけど解説はMACだけね) - albatrosary's blog

以下は、私のMacに入っているバージョンです。

バージョン確認

$ brew -v
Homebrew 0.9.5 (git revision ff9a; last commit 2016-01-08)

$ node -v
v5.4.0

$ npm -v
3.3.12

私は、node.jsが古いと言われたので、最新にしました。

$ brew upgrade node

インストール

その後、yoと周辺Generatorのインストールを行います。

$ npm install -g yo
$ npm install -g generator-angular

問題なくインストールができたら、プロジェクトを作りたいディレクトリに移動して下記コマンドを叩いてみます。

$ yo angular

色々聞かれますが、必要な機能のGeneratorを選択しましょう。Gulpでもいいですが、Yeomanでの解説サイトはGruntの例が多いので、Gulpだとハマった時に大変かもしれません。
なお、angular以外にもwebappなど様々なGeneratorが存在します。generator-fullstackという、MEANスタック環境が一瞬で構築できるGeneratorもあったりしますので、興味のある方は調べてみてください。

実行

下記コマンドでサーバーが立ち上がり、編集したコードがページ更新無しにリアルタイムで反映されるようになります。
注意点として、上記の$ yo angularでGulpを選択した場合、下記コマンドは使えません。($ gulp で良かったはず)

$ grunt serve

終わりに

特に問題なく導入できたかと思います。導入時のトラブルの少なさも人気の一因なのかもしれませんね。
私の考えでは、最初はyeomanに頼らずにイチから構築し、2回目以降の作業効率化のためにYeomanといった開発支援ツールを使うのが理解が深まると考えています。
そういう私は今書籍ベースで理解を深め中です。

WEB上の情報だけで体系的に学ぶのが難しそうだった(特にビジネスロジック周り)ので、本の力を借りることにしました。著者の山田祥寛さんの本にはいつも助けられています。

AngularJS アプリケーションプログラミング

AngularJS アプリケーションプログラミング

JavaScriptのオブジェクトに関するメモ(基礎)

JavaScriptの復習のアウトプットとして、メモ書きしていきます。
最下部に勉強に使用した書籍の紹介も行っています。

そもそも、オブジェクトとは

名前付きのプロパティ(値)の集合体を格納するためのコンテナ(入れ物)のことです。

自然言語の場合

自然言語でテーブルデータとして扱う場合で考えます。

Yamada

プロパティ名* プロパティ値*
name Yamada Taro
email yamada@xxxxx.xxx
password yamada_password

直感的ですよね。Yamadaという人のフルネームがYamada Taroで、メールアドレスは・・・ということがわかると思います。

ただ、このままの自然言語ではJavaScriptでは扱えないので、上記のテーブルをJavaScriptのオブジェクトに変換します。

JavaScriptの場合

// Yamada オブジェクトを生成
var yamada = new Object();

// yamadaオブジェクトにプロパティを格納
yamada.name = 'Yamada Taro';
yamada.email = 'yamada@xxxxx.xxx';
yamada.password = 'yamada_password';

いかがでしょうか。テーブルの状態と対比すると分かりやすいのではないでしょうか。
yamadaオブジェクトは、メソッド(操作)を使わなければただのデータベースですので、次はオブジェクトを使用するためのメソッドについて記述していきます。

なお、開眼!JavaScriptに書いてある下記の言葉がとてもためになりました。

オブジェクトとは、名前と値を持つプロパティを格納するコンテナにすぎない。

メソッドについて

早速、先ほどの自然言語で作成したテーブルにメソッドに相当する部分を追加してみます。
Yamada

プロパティ名 プロパティ値
name Yamada Taro
email yamada@xxxxx.xxx
password yamada_password
getName nameの値を返す

次に、JavaScriptの場合

// Yamada オブジェクトを生成
var yamada = new Object();

// yamadaオブジェクトにプロパティを格納
yamada.name = 'Yamada Taro';
yamada.email = 'yamada@xxxxx.xxx';
yamada.password = 'yamada_password';
yamada.getName = function() {
  return yamada.name;
};

yamadaオブジェクトのプロパティとして設定したgetNameメソッドは、yamada.nameというプロパティの値を返します。こういったメソッドがないと、オブジェクトは静的なデータを格納するに留まってしまいます。

本来は関数として定義して、yamadaオブジェクトをインスタンス化して使うのですが、この記事ではそこまでは踏み込みません。上記だと、yamada以外の人を追加する場合、毎回xxxx.name = ....といった記述をしなければなりません。
参考までに、ソースを下記に記述します。

var Person = function(name, email, password) {
  this.name = name;
  this.email = email;
  this.password = password;
  this.getName = function() {
    return this.name;
  }
};

var yamada = new Person('Yamada Taro', 'yamada@xxxxx.xxx, 'yamada_password');

このようにすることで、新しい人を追加する場合は

var yamada = new Person('Yamada Taro', 'yamada@xxxxx.xxx, 'yamada_password');

このコードのみコピペしてきます。

メソッドについて、もう少し分かりやすく書いてみます。

プロパティ メソッド
(状態や特性) (操作する道具)
姓、名 姓名をくっつける
性別 性別を出力

こちらの方がより直感的に理解出来るかもしれません。
余力があれば、上記のオブジェクトをJavaScriptで書いてみてください。

var Userinfo = function(name1, name2, sex) {
  this.name1 = name1;
  this.name2 = name2;
  this.sex= sex;

  this.name = function() {
    return this.name1 + this.name2;
  }
  this.sex = function() {
    return this.sex;
  }
}

今回はここまでにします。
次回はコンストラクタインスタンスに関することを書いてみようと思います。

参考書籍(一部文言を引用させていただいております。)

開眼!  JavaScript ―言語仕様から学ぶJavaScriptの本質

開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質

【JavaScript】ノード要素取得方法あれこれ

フロントエンドエンジニアという立ち位置において、JavaScriptの理解は必須要件となってます。そこで、読み込む書籍を探していたわけですが、以下の書籍に絞りこみました。

 

JavaScript本格入門 ?モダンスタイルによる基礎からAjax・jQueryまで

JavaScript本格入門 ?モダンスタイルによる基礎からAjax・jQueryまで

 

 

JavaScript 第6版

JavaScript 第6版

 

 

パーフェクトJavaScript (PERFECT SERIES 4)

パーフェクトJavaScript (PERFECT SERIES 4)

 

 

開眼!  JavaScript ―言語仕様から学ぶJavaScriptの本質

開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質

 

Amazonブクログジュンク堂での立ち読みを経て購入したのが下記2冊です。サイ本は時期尚早と見て見送りました。この2冊読破してからかなと。

 

JavaScript本格入門 ?モダンスタイルによる基礎からAjax・jQueryまで

JavaScript本格入門 ?モダンスタイルによる基礎からAjax・jQueryまで

 

 こちらは、入門書だけどもしっかりとクロージャーやらオブジェクトやらの話にも言及している本で、他の言語を知っている人のJavaScriptへの取っ掛かりとしては最適だと判断して購入しました。実際読み進めていくと実践は少ないのでザ・座学といった感じですが、JavaScriptとは何たるか、が理解できてきているように感じます。

 

開眼!  JavaScript ―言語仕様から学ぶJavaScriptの本質

開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質

 

 こちらは、オライリーから出版されているフクロウ本?(っていうのかな)です。この本も実践編というわけではないのですが、オブジェクトやクロージャ、prototypeに対してまさしく開眼!させてくれる本のようです。

まだ読み進めて間もないので詳しい書評は書けませんが、上記2冊を通して実用に耐えうる言語仕様理解を進めていきたいと考えています。

以下は、JavaScript本格入門のメモです。

絶対位置でのノード要素取得方法

getElementByIdメソッド

documentオブジェクトの、getElementByIdメソッド。IDを取得する。

 

document.getElementById('result').innerHTML = 結果が入る

<div id="result">★ここに入る★</div>

 

getElementsByTagNameメソッド

同じくdocumentオブジェクトのメソッドであり、タグの要素名を指定する。IDをキーとするgetElementByIdとは異なり、タグは複数の要素が合致する場合があるため、要素の集合(NodeListオブジェクト)をリターンする。

注意点としては、ElementではなくElementsである点。

WordPressで目次リストを作成するプラグインに「Table of Contents Plus」があるが、目次に関しては、このメソッドを使うことでhタグを取得し一覧表示させることができれば容易に実装が可能であるため、プラグインに頼らずとも実装可能となる。

window.onload = function() {
  var result = ;
  var list = document.getElementsByTagName('a');
  
  for (var i = 0; i < list.length; i++) {
    result.push(list.item(i).href);
  }
 
  window.alert(result.join('¥n'));
}
引用:JavaScript本格入門(259ページ)

NodeListオブジェクトから利用できるメンバはlength, item(i)の2種類。 

getElementsByClassNameメソッド

こちらは、class属性をキーにノードを取得するメソッド。ただし、TagNameと同様にクラスは複数存在sるため、戻り値はNodeListオブジェクトとして返却される。

具体的な使い方はgetElementsByTagNameと同じであるため割愛する。NodeListオブジェクトも同じ。

相対位置でのノード要素取得方法

getElementById、getElementsByTagName、getElementsByClassNameメソッドはどれも特定の要素ノードを取得するためのメソッドであるが、相対的にDOMでノードを取得することもできる。

カレントノードに対して以下のプロパティがある。名前は直感的なのですぐ覚えられるはず。childNodesプロパティはNodeListオブジェクトが返却される。

  • parentNode(親ノード)
  • previousSibling(兄ノード)
  • nextSibling(弟ノード)
  • childNodes(すべての子ノード)
  • firstChild(最初の子ノード)
  • lastChild(最後の子ノード)

childNodesプロパティを使う場合の注意点として、空白はテキストノードして扱われる場合がある(ブラウザ依存)。
そこで、optionタグなど、特定要素のみを取り出したい場合は、nodeTypeプロパティを使って要素ノードを取得する必要がある。

属性値の取得

getAttribute/setAttributeメソッド

要素取得には、前述のclassName(DOM)等があるが、実際のHTMLではclassと名前が異なる。そこで、本メソッドを使うことで同名でのアクセスが可能となる。

不特定の属性取得

attributesプロパティを使用することで、特定の要素ノードに属するすべての属性を取得できるようになる。attributesプロパティの戻り値は、NamedNodeMapオブジェクトとなる。NodeListオブジェクトにも似ている。
名前、インデックス番号、両方でアクセスが可能。
lengthとitem(i)、それからノード取得のためのnodeName, nodeValueプロパティがある。

IEでattributesプロパティを使うと、未定義の全属性が出力されてしまうため、よほどのことがない限りはgetAttributeメソッドを使ったほうが良さそう。

window.onload = function() {
  var logo = document.getElementById('logo');
  var attrs = logo.attribute;
  var result = ;
 
  for(var i = 0; i < attrs.length; i++) {
    var attr = attrs.item(i);
    if(attr.nodeValue) {
      result.push(attr.nodeName + ':' + attr.nodeValue);
    }
  }
  window.alert(result.join('¥r¥n');
}
 

引用:JavaScript本格入門(265ページ)

ノードの追加

innerHTMLプロパティ

innerHTMLは、プロパティ。
DOM標準で決められたプロパティではないが、主要ブラウザに対応している。

document.writeではレンダリングブロックが発生するため、innerHTMLを使うこと。document.writeを使う場合はasyncで非同期読み込みすること。

まとめ

こんな感じで、少しずつ気になったフレーズや、実際に使えそうなパーツを抜粋していこうと思っています。少しでも参考になれば幸いです。

達人に学ぶDB設計徹底指南書を読む

きっかけ

簡易的なECサイトを作ろうと思った時にパッと具体的なDB構造がイメージできないことに深い悲しみを覚え、紹介していただいた書籍を購入し読んでいくことにしました。

達人に学ぶDB設計 徹底指南書 初級者で終わりたくないあなたへ

達人に学ぶDB設計 徹底指南書 初級者で終わりたくないあなたへ

 

 この書籍は、ミックさんという方が執筆されています。良質でボリュームのあるデータベース解説サイトを運営されていて、評判も非常に良いです。

現時点のスキル

この通り、ほぼ初心者と言っていいレベルだと思います。

この本を読むことでどれだけ自分がレベルアップできるか期待しつつ、この記事内で感想やためになったことを追記していきます。

 

※ 一緒に読もうよ!って方いましたら是非お声がけください!

データベース用語の整理

ここでは、もう忘れてしまったデータベースの用語を整理していきます。どちらかというと抽象的な内容となりますが、折角読んだものを少しでも忘れないようにするためにアウトプットしていくことが目的です。

3層スキーマ

  1. 外部スキーマ(外部モデル)=ビュー
  2. 概念スキーマ(論理データモデル)=テーブル
  3. 内部スキーマ(物理データモデル)=ファイル

いきなりイメージしづらい用語が並んで多少困惑気味です。当時は資格取得のために割りきって勉強していましたが、いざ実務と絡めようとすると結局何も分かっていなかったんだなと痛感させられます。。

  • スキーマは枠組みと覚える。
  • 外部スキーマは「ユーザーから見たデータベースの姿」。ユーザーから見えるシステムの姿の一部。ユーザーにどのようにデータを見せるか、ということ。
  • 概念スキーマは「開発者から見たデータベース」。テーブルの要素やデータ同士の関係を示すもので、論理設計とも呼ぶ。データベース設計の中心となるスキーマとなる。
  • 内部スキーマは「DBMSから見たデータベース」。テーブルやインデックスの物理的定義を含む。あらゆるデータは最終的にはファイルで表現される、と考える。論理設計との対比で物理設計と呼ぶ。

ここまで読んでも、いまいちイメージできない状況です。結局のところ実際のシステムにおいて3層スキーマがどのように作用しているか対比しないと分からないんじゃないかと感じています。

幸い、次の章以降で詳しく落とし込んでいくようなので、どこまで理解できるようになるか楽しみをとっておきます!

WordPressのパンくずリストってどうやって生成されているのか?

はじめに

スクラッチで簡易的なECサイトを作ろうと思った時に、PHP+MySQL初心者の自分にとって最初の壁はパンくずリストです。 商品の追加やユーザー追加等はDBへのINSERT、DELETE、UPDATEなどで対応できますが、パンくずリストで先祖カテゴリまで取得ってどうするの?という疑問が生まれました。

ちょっと調べてみると、データベースの木構造を理解する必要がある、隣接リストが一般的だが毎回SQL文を発行するのはアンチパターンだ、など情報が入り乱れて整理ができないのです。 そこで、世界中で使われているWordPressの仕組みに乗っかれば大きく外さないのでは?ということで調べてみました。

WordPressパンくずリストは一般的に誰でも導入していると思います。ただ、仕組みまで理解している人はそれほど多くないのではないでしょうか。この関数をこういったループで回して・・といった使用方法に留まっているケースが大半?のはずです(違ったらごめんなさい)。 こんな記事でも誰かの参考になってくれると嬉しいです。

肝になるのはget_ancestors()

WordPressにおけるパンくずリストの仕組みとして、まずは現カテゴリのデータベースで保持しているparent情報を見て、親カテゴリが存在すればget_ancestors()が呼ばれます。

データベース構造例
ID カテゴリ名 親カテゴリID
1 カテゴリA 0
2 カテゴリB 0
3 カテゴリC 1
4 カテゴリD 3
5 カテゴリE 2

上記が隣接リストで、ツリーにすると以下の感じになります。

カテゴリA
├カテゴリC
 ├カテゴリD
カテゴリB
├カテゴリE

カテゴリDのページにおいて、パンくずリストを表示すると、
カテゴリA > カテゴリC > カテゴリD

になっておく必要がありますよね。

get_ancestors(カテゴリD, category)とすると、先祖カテゴリが配列で返ってきます。

Array
(
[0] => 3
[1] => 1
)

この仕組みを利用してみんなget_ancestorsを使うわけなんですが、本記事ではこの関数の中身を覗いてみます。
中はループになっていて、

  1. $term = get_term(現カテゴリID, category); 現カテゴリIDを$termにセット
  2. $ancestors[] = $term->parent; 親カテゴリIDを$ancestors配列にセット
  3. $term = get_term($term->parent, category); 親カテゴリIDを$termにセット

以降、親カテゴリIDが0になるまで2、3を繰り返す

結果的に、以下の配列が$ancestorsに格納されるという仕組みです。注意しないといけないのは、$ancestorsには深い階層のカテゴリIDから順番に配列に格納されていますので、array_reverse()関数で逆順にして操作した方が良いです。

Array
(
[0] => 3
[1] => 1
)

なお、get_term()内のget_instance()内でSELECT文を発行していることから、階層を1つずつSQL文で追っかけているんだと思われます。つまり、深い階層では何度もSQL文を叩いているので、大規模なサイトになるとデータベースに負荷がかかってきそうですね。

結論

簡易的なカテゴリ階層を作る際は、隣接リスト方式で実施する。
(もちろん、色々ご意見あると思いますので、アドバイスなどいただけると大変うれしいです)

はてブ開始

簡単なプロフィールです。 WEB開発、コンサル等をやっている個人事業主です。何でも屋みたいな感じで、突出したスキルがないことに最近悩んでいます(本気)。

もともとは、フィーチャーフォンスマホの開発エンジニアを6年ほどやっていました。いわゆる要素技術開発で、新機能開発や既存機能の性能改善、コード削減、フィールドテスト、当時も何でもやっていた記憶があります。コードはCやC++です。

一方、WEB技術に関する知識は初心者レベルに近く、勉強していく過程をアウトプットしていこうと考え「はてなブログ」を始めてみました。

下記のジャンルに関して書くつもりですが、殆ど雑記のような感じで自分用のメモ帳代わりになると思います。 凝った文章、内容を作ろうとするとどうしても億劫になり続かないということが容易に想像できますので、 まずはどんな内容でもいいのでアウトプットし続けるという方向性でやっていきます。