急がば回れ「初めてのPHP5」の紹介

「今からプログラミング(PHP)はじめたいなあ」という方へ。
パソコンスクールで学ぶことやネットで独学するのも間違いなくいい方法です。

私はオライリージャパンから出ている「初めてのPHP5」をおすすめします。

なぜでしょうか?

彼らは特定の分野に特化した方法を教えてくれます。
つまり、部分的なことしか教えてくれません。

「知識が穴だらけやん・・・」
ネットでずっと独学してきた私は「初めてのPHP5」を読んで、このことを改めて知りました。

その例を1つ挙げます。
私はnumber_format()関数に衝撃を受けました。

<?php
print number_format(285266237);
?>

表示
285,266,237

ただ単に「数値を見やすくする」方法です。
ですが・・・これを実現するコードは難しそうですね。

もし、このコードを実装しなければならないとなった時を想像してみてください。
存在することを知っていれば「1行」です。
知らなければどうなることやら。

これは他のものにも言えるのでは?と思います。
「方法を知らなければうまく出来ない」と。

この本にも弱点があります。
細かいところまで深く書き過ぎていることです。
あまり好きじゃない人にとっては苦痛かもしれません。

ですが、細かいということは、
「なぜ?」「どうして?」をちゃんと理解できることに繋がります。

基礎を学ぶためにも「初めてのPHP5」は大事だと思います。

結局、基礎がないとどの言語にも応用できません。
「急がば回れ」です。

まとめ読み バージョン1.1.1のリリース

フリーソフト「まとめ読み」バージョン1.1.1のリリースを行いました。

まとめ読み ダウンロードページ

変更点

  • 検索方法の変更
  • 検索マッチングの先を、「タイトル&内容」「内容」の2つに変更しました。

  • 不必要なHTMLの修正
  • リンクの修正、Twitterのガジェットを削除しました。

  • 表示スタイルの変更
  • ボタン(buttonタグ)の表示を変更しました。

  • 表示の修正
  • 細かな表示のミスを修正しました。

TechCrunch(英語版)のススメ

techcrunch
「英語」と聞いただけで敬遠する方もいらっしゃるかもしれません。
しかし、「やらないと慣れない」のは事実。

慣れるには「好きなものだけ」読めばいい!
すごく簡単ですよね?

1週間に1記事だけでも、全く別の世界が見えてきます。

TechCrunch(英語)
でもやっぱり日本語も読みたい方は以下をどうぞ。
TechCrunch(日本語)

翻訳は適当でも何となく意味がわかるGoogle翻訳がおすすめ!
翻訳に時間がかかると読むのが面倒になりますよね。

GoogleGrassなどのウェアラブルなものが今年のトレンドとなるでしょう。
Grassをつけておくだけで翻訳も勝手にしてくれる時代になると思います。

実際に自分でできることも大事だと思いますよ!

見よう見まねでGitHubでmatomeyomiを公開する

「GitHub」をエンジニア用のSNSと聞いたのではじめてみました。
理由は「他人のコードが見たい!」と、ただそれだけでした。

全て英語ですね。

↓使い方がわからない方はこちら
黒い画面とかよくわからない人のための、ゆるふわgit入門 ~github for Windows~を参考に。

インストール
アカウント作成
サイト巡回

・・・で中身を見てみるとPSRで使ったクラスローダー(SplClassLoader.php)の公開先でした。orz

とりあえず作ったアカウント名はGitHub R2002です。
もっと良いものを出していきますね!

まとめ読み バージョン1.1.0のリリース

フリーソフト「まとめ読み」バージョン1.1.0のリリースを行いました。

まとめ読み ダウンロードページ

変更点

  • 対象をPHP5.3.7以上に変更
  • 読み込み速度および安全性の確保
    SplClassLoader.php、オブジェクト指向の導入

  • 安全上問題のあった箇所を改良
  • PDOの導入

  • 煩雑だったセットアップの手順の簡略化
  • 「matomeyomi」データベースを作成するだけでOKに

注意点

「Mobile_Detect.php」「password.php」「SplClassLoader.php」それぞれの著作者は別の方です。

コメント

気付いたことがありましたらコメントをお願いします。

現代PHPの正しい道「PHP: The Right Way」の紹介とその要約

時代遅れの本や情報があふれている。そのため「何年前のコレ?」というコードが広まっている。

私もまずいコードを書いていた。悪意がある頭のいい人が少し手を加えるだけでデータベースが死んでしまうようなコードを。

「PHP: The Right Way」はそれを正すとても良いサイトだ。
PHP
初心者を始めとして、中級者、上級者の方も。

PHPで開発するにはWebサーバが必要だ。

でも大丈夫。
サーバーは自分のPCでOK!
方法はXAMPPで自宅サーバーを作るを参考にして欲しい。
PHPバージョンは最新バージョン(5.5)がオススメ。

コーディングスタイルはPSR!
これはDrupal や Zend、Symfony、CakePHP、phpBB、AWS SDK、FuelPHP、Lithium の開発者たちが集まって作ったPHPのコーディングスタイル。
コーディング規則PSRを学ぶを参考にして欲しい。

データベースは PDO か mysqli を使ってアクセスすること。
「mysql_connect」関係の関数は使えなくなることが予定されている。

と・・・まあいろいろあるが、読んで試してみてほしい。
もっとコードが読みやすくなるだろう。
私のコードは確実に読みやすくなったしサイトの安全性も上がった。

PHPは良い言語だ。
だからもっと良い言語にしていけるように頑張りたい。

[PHP]まとめ読みをPSRで改良する(4)


まとめ読みをPSRで改良する(3)から約一週間。

こんがらがっていた頭の中がすっきりして、なんとなくですがオブジェクト指向がわかってきたような気がします。

オブジェクト指向で大事そうなのは、機構(機能の固まり)を分けること。
データベースへの通信ならそれだけで1つの変数に格納する。

たとえば「$dataBase->….;」という感じで。

これだと名前空間の汚染?が無くなる。自作の関数被りが無くなるって言った方がわかりやすいかな。

そしてPSR規則にのっとりつつ・・・って感じですね。

<?
require_once 'SplClassLoader.php';
require_once 'password.php';
require_once 'Mobile_Detect.php';

// クラスローダー
$classloaderBase = new SplClassLoader('ReiFarms', './lib');
$classloaderBase->register();

// 拡張
$dataBase = new ReiFarms\DataBase();
$config = new ReiFarms\Matomeyomi\Config();
$display = new ReiFarms\Matomeyomi\Display();

// MySql
$dataBase::setInfo($config->dbInfo);

携帯判定(mobile_detect)もそのまま使えました。

// 携帯判定
$detect = new Mobile_Detect;
if(empty($_SESSION['isMobile']))
{
    $_SESSION['isMobile'] = $detect->isMobile() ? true : false;
}

これは便利!

本題のプログラムはこんな感じで書いています。
今のところは問題はなさそう。

<?php
require_once './lib/Matomeyomi.php';

// DataBase
$dataBase->connectDb();

// Html
$html = null;

// 初期設定
$blogAll = [];
$blogWeekCount = [];
$blogAllCount = [];
$htmlArticleWeek = null;
$htmlArticleAll = null;
$htmlBlogWeek = null;
$htmlBlogAll = null;

// 初期読み込み
$sql = $dataBase->query("SELECT * FROM blog");
if($sql){
    while($Blog = $sql->fetch(\PDO::FETCH_ASSOC))
    {
        $blogAll[$Blog['id']] = $Blog;
        $blogWeekCount[$Blog['id']] = $Blog['count'];
        $blogAllCount[$Blog['id']] = $Blog['count_all'];
    }
    
    // 記事ランキング
    $i = 1;
    $sql = $dataBase->query("SELECT id, blogid, title, count, count_all FROM article ORDER BY count DESC");
    while($Article = $sql->fetch(\PDO::FETCH_ASSOC))
    {
        if(!$Article['count'])
        {
            break;
        }
        // 取得
        if(empty($blogWeekCount[$Article['blogid']]))
        {
            $blogWeekCount[$Article['blogid']] = 0;
        }
        $blogWeekCount[$Article['blogid']] += $Article['count'];
        if(empty($blogAllCount[$Article['blogid']]))
        {
            $blogAllCount[$Article['blogid']] = 0;
        }
        $blogAllCount[$Article['blogid']] += $Article['count_all'];
        // 表示
        if($i < 50)
        {
            if($htmlArticleWeek)
            {
                $htmlArticleWeek .= "<tr><th></th></tr>\n";
            }
            $htmlArticleWeek .= $config->rankArray('Article', $i, $Article['count'], $Article);
            $i++;
        }
    }
    if(!$htmlArticleWeek)
    {
        $htmlArticleWeek = "<tr><th>データがありません</th></tr>\n";
    }
    
    // 人気記事
    $i = 1;
    $sql = $dataBase->query("SELECT id, blogid, title, count_all FROM article ORDER BY count_all DESC");
    while($Article = $sql->fetch(\PDO::FETCH_ASSOC))
    {
        if(!$Article['count_all'])
        {
            break;
        }
        // 表示
        if($i < 50)
        {
            if($htmlArticleAll)
            {
                $htmlArticleAll .= "<tr><th></th></tr>\n";
            }
            $htmlArticleAll .= $config->rankArray('Article', $i, $Article['count_all'], $Article);
            $i++;
        }else{
            break;
        }
    }
    if(!$htmlArticleAll)
    {
        $htmlArticleAll = "<tr><th>データがありません</th></tr>\n";
    }
    
    // ブログランキング
    if($blogWeekCount)
    {
        arsort($blogWeekCount);
        $i = 1;
        foreach($blogWeekCount as $blogId => $num)
        {
            if(!$num)
            {
                break;
            }
            $Blog = $blogAll[$blogId];
            if($Blog['status'] != 1)
            {
                continue;
            }
            if($i < 50)
            {
                if($htmlBlogWeek)
                {
                    $htmlBlogWeek .= "<tr><th></th></tr>\n";
                }
                $htmlBlogWeek .= $config->rankArray('Blog', $i, $num, $Blog);
                $i++;
            }else{
                break;
            }
        }
    }
    if(!$htmlBlogWeek)
    {
        $htmlBlogWeek = "<tr><th>データがありません</th></tr>\n";
    }
    
    // 人気ブログ
    if($blogAllCount)
    {
        arsort($blogAllCount);
        $i = 1;
        foreach($blogAllCount as $blogId => $num)
        {
            if(!$num)
            {
                break;
            }
            $Blog = $blogAll[$blogId];
            if($Blog['status'] != 1)
            {
                continue;
            }
            if($i < 50)
            {
                if($htmlBlogAll)
                {
                    $htmlBlogAll .= "<tr><th></th></tr>\n";
                }
                $htmlBlogAll .= $config->rankArray('Blog', $i, $num, $Blog);
                $i++;
            }else{
                break;
            }
        }
    }
    if(!$htmlBlogAll)
    {
        $htmlBlogAll = "<tr><th>データがありません</th></tr>\n";
    }
}else{
    $htmlArticleWeek = $htmlArticleAll = $htmlBlogWeek = $htmlBlogAll = "登録されていません";
}

$html = $config::readHtml('ranking.html');

// 置き換え
$html = str_replace('${htmlArticleWeek}', $htmlArticleWeek, $html);
$html = str_replace('${htmlArticleAll}', $htmlArticleAll, $html);
$html = str_replace('${htmlBlogWeek}', $htmlBlogWeek, $html);
$html = str_replace('${htmlBlogAll}', $htmlBlogAll, $html);

// Display
$display::setHtml($html);
$display->sub();

// アクセス解析
$config->access();

最後で置き換え。
これでHTML中の何処へでも入れ込むことができるようになってます。
「便利だけどこれでいいのか!」という気持ちはありますね。

やっぱり、まだまだ未熟者。

知らなかった!「while」と「do while」の違い

amazing
Perl→PHPを独学でやって現在C言語をやってます。
「do{ ~ }while( ~ );」←ナニコレ状態でした。

「while」と「do while」の違いは、
「前」で条件判定をするか、「後ろ」でするかの違いだけでした。知らなかった・・・。

<?php
$i = 0;
while ($i > 0) {
    echo $i;
}
?>

実行結果は何も表示されません。

<?php
$i = 0;
do {
    echo $i;
} while ($i > 0);
?>

実行結果は「0」と表示されます。

何か使えそうだけど今は思いつかない\(^o^)/

Cで簡単プログラミング「二次関数の解」

C言語で簡単なプログラミングをしましょう!
今回は「二次関数の解」です。

↓Cはコンパイル(機械語に翻訳)が必要なので、以下でコンパイラの「MinGW」をインストールしてください。
C言語およびC++のコンパイラMinGWのインストールとテスト

二次関数の解を求める理由

理由は簡単です。
「物が落ちてくる秒数を予想できる」
「ある距離(高さ)まで飛ばすのにいくら力が必要かわかる」

「200mの高さから物体を落とすと何秒後に落ちる」がわかります!
暗算でできたらすごい!

コード

ファイル名は「2ji.c」にします。
コピー&ペーストではなく、自分で書くとGood!

/*--------------------------------------*/
// 2次方程式の解
/*--------------------------------------*/
#include <stdio.h>
#include <math.h>

int main()
{
	double a, b, c, d, x, x1, x2;
	
	// 係数読み込み
	printf("二次関数の係数a,b,cは?");
	scanf("%lf %lf %lf", &a, &b, &c);
	
	// 1次方程式の場合
	if(fabs(a) <= 1.0e-10)
	{
		if(fabs(b) <= 1.0e-10)
		{
			printf(" 解を求めることができません");
		}else{
			x = -c/b;
			printf(" x=%f\n", x);
		}
		
	}
	// 2次方程式の場合
	else{
		d = b*b-4.0*a*c;
		// 2実数
		if(d >= 0.0)
		{
			d = sqrt(d);
			x1 = 0.5*(-b-d)/a;
			x2 = 0.5*(-b+d)/a;
			printf(" x=%f %f\n", x1, x2);
		}
		// 虚数
		else{
			d = sqrt(-d);
			x1 = -0.5*b/a;
			x2 = 0.5*d/a;
			printf(" x=%f ± i%f", x1, x2);
		}
	}
	return 0;
}

結果、動き

コンパイルが成功すると以下のように表示されます。
コンパイル成功

いろいろと計算してみます。
適当になんでも好きなように!
計算してみる

「200mの高さから物体を落とすと何秒後に落ちる」答え
答え
約6.4秒後だそうです。
エレベーターが自由落下した時に使えるかもしれない無駄知識!

予想できるエラー

エラー1
In function main ”main”関数の中で、
12: error: stray ‘\129’ in program 12行目に”stray”(全角文字)があるよ!’\129’とかいう
12: error: syntax error before “G” “syntax”(構文)にエラーがあるよ!”G”の前に

文字コードエラー
文字コードエラーです。
「ShiftJis」に文字コードを変えてね!
文字コードって何?という方は→文字コードの基本と応用

[PHP]まとめ読みをPSRで改良する(3)

Cord
(2)の記事から「PDO」を使い、データの通信をオブジェクト化しました。
password_hashを使い、パスワード処理の暗号化も行いました。

PDOを導入する一番の理由は「mysql_query」などは近い内に使えなくなるようです!

ネイティブドライバについては、もうひとつ注意すべきことがある。 PHP 用の mysql 拡張モジュールの開発はすでに終了しており、PHP 5.4.0 の時点での公式発表によると 「長期的には廃止予定」だ。つまり、近い将来に削除されるということであり、 PHP 5.6 (になるかどうかわからないけど、5.5 の次にくるやつ) の頃には使えなくなるだろう。
(PHP The Right Way.より)

PDOは「PHP Data Objects」の略で、どのデータベースを使っているかを隠蔽してくれるもの(のよう)です。
使えるのはMySQL、PostgreSQL、SQLiteなど。

PDOの接続方法

PDOの利用の方が詳しいですが、どう使うのかは載っていません・・・。

Class内の関数に入れるのなら

    // DBに接続
    public function connectDb()
    {
        $dsn = 'mysql:dbname=' . self::$dbInfo['name'] . ';host=' . self::$dbInfo['host'];
        try{
            self::$db = new PDO($dsn, self::$dbInfo['user'], self::$dbInfo['pass']);
        }catch (PDOException $e){
            print('Connection failed:'.$e->getMessage());
            die();
        }
    }

設定の書き方

public $dbInfo = [
        'host' => 'localhost', 'name' => 'database', 'user' => 'root', 'pass' => ''
    ];

設定を導入する関数と必要なものを記述すること!
これはDBに接続すると同じ所で使うといいかも?
(そもそも使い方がおかしいかもしれない)

    private static $dbInfo;
    private static $db;
    // DBの情報を設定
    public static function setInfo($dbInfo)
    {
        self::$dbInfo = $dbInfo;
    }
    // DBの接続切断
    public function disconnectDb()
    {
        self::$db = null;
    }

暗号化方法password_hash(password_compact)の使い方

さくらサーバーはPHP 5.4までしか使えない問題があります。
PHP5.5で導入された「password_hash」が使えない・・・。

↓解決策
PHP5.5から使える暗号化「password_hash」を「password_compact」を使って以前のバージョンで利用する
すごく簡単です。

現状

ミニ四駆ブログまとめ

  • 表示
  • PC、スマートフォン両方利用可能です。
    > PC表示
    PC
    > スマートフォン表示
    スマホ

  • PDOでのDB通信で安全化の強化
  • 「?id=1%3BDELETE+FROM+users」のようなデータを受け取らないようにしました。
    以前のバージョンではできます/(^o^)\

  • password_compactで管理パスワード比較の安全化
  • パスワード自体の変換(保存用)は「crypt」を使っています。

  • 読み込み速度の向上
  • 「使っていた関数を見直す」
    「更新されていないRSSを読まない」
    「RSS情報は受け取るが、日付がある程度過去の場合更新しない」
    「無駄な読み込みはなくす」

    まとめ

    現在、サイトの動作をテストしています。
    特に問題はなさそう。
    一週間行って問題がなさそうなら公開・配布しますね!

    でもオブジェクト指向の書き方、MVCの書き方にそぐわなさそうなので少しずつ改良していきます!