今年もPHPカンファレンス福岡2018行って来たよ^^

先週、PHPカンファレンス福岡2018に行って来ました!
去年も行ったんですが、あいかわらず楽しかったです。

公式サイト:https://phpcon.fukuoka.jp/2018/

カンファレンス後の気持ち

  • 英語の文でも逃げずに読む
  • 日本語の文あればなお、ありがたくしっかり読む
  • PSRおさらいしよう
  • ログ使おう
  • 自動化したい
  • Golangが熱いらしい
  • もっと勉強しよう

全然野菜・前夜祭

前乗りしたので、全然野菜と前夜祭にも参加してきました。
全然野菜の開催場所がさくらインターネットさん、前夜祭がLINE fukuokaさんでした。
他社のオフィスを見学できるのもいいですよね。面白いです。
LINE fukuokaさんでは、テーマパーク状態で超興奮しました。
カフェスペース的なところで3セッション同時で進行しており、
私は真ん中で全部見ようと欲張っていましたが、無理でした。。。
同世代女性エンジニアとも知り合えていい機会でした\(^^)/

本編

会場は去年と同じく、FFTホールでした。
去年も見たことある人がいっぱいいてなんか安心しました。
メルカリのトートバックもいただけたし、
愛用PHPStormのJetBrainsのヨーヨーも狙ってたので、やっとGETできて大満足でした!

 

私的に面白かったのが

です。

社内ナレッジを全部署統一してて、内容はなんでもokってカオスかなと思ったんですが、めちゃくちゃいいなって思いました。

私は生活レベルが低いので、管理とか人事の方からお金の話とかあったら見たいし、役立ちそうだなって思います。

技術の話だけではなくて、他社の業務効率化の話を聞くのって面白いなって思いました。

 

実行委員の皆様、お疲れ様でした。
今年も開催していただき、本当にありがとうございました!

 

ところで、もちろん

\PHPカンファレンス関西2018行きます!/

https://2018.kphpug.jp/

 

 

/細かいことは下記リンクにまとめました。よかったらみてください。\

https://kin29.github.io/PHPerMemo/

number_format に小数点以下がある値を渡すのは危ない時がある。

 

\ヘビロテな曲紹介コーナー、はじめました。/

最近、今更ながらこの歌にはまってます。
メリールー/SIX LOUNGE
このギター弾きたくて、耳コピしようとしてるけど、全く進まんです。

 

Googleアナリティクスについてではないです、はい。
次に書きますw
今日はPHPの関数number_formatが怖いことに気づいたので書いておきます。

php.netより:number_format

 

「金額表示で千円以上の時、見やすくしてくれるんだー」って、
この関数をね、小数点発生する値でつかってたんですね、第一引数だけで・・・・
こんな感じ(下)

<?php 

$number1 = 1000.499999; 
echo(number_format($number1));   //1,000

echo("\n");

$number2 = 1000.500000;
echo(number_format($number2));   //1,001

 

( ^ω^ )え、小数点第一位で四捨五入しちゃってるやん。

(なんも指定してないのに)そんなこと求めてないよ。

 

ってなりました。

第二引数を指定しないと、デフォルトの0(=小数点以下の桁数が0)とみなされ、

小数点第一位で四捨五入しちゃいます。

 

てことで、第二引数で、小数点以下が何桁か指定すればいいんだ!

って思ったけど、そんなの予想できない時が大半だと思います・・・。

 

だから、小数点以下が発生しうる値にnumber_format使うときは一旦考えましょう。

小数点以下の桁数が、固定のときは第二引数をきちんと指定すれば、想定通りになるかと思います。

 

 

BEAR.SundayでAPIを作ってみた。

 

ども!最近、久々の一人暮らしになった私です。自由ですね。

前回の記事でクイックスタートをやってみたBEAR.Sundayですが、
APIが簡単に作れるということで、なんか使えるAPI作りたいなと考えました。

 

\名言APIを作りました。/

https://today-saying.herokuapp.com/

名言チョイスはわたし好みです。リロードしたらランダムにでます。
偉人のお言葉ってなんか元気でます!元気ない人は是非みてください!!

(攻撃はやめてくださいねw)

〜こんなやーつ〜
・名言を登録できる(INSERT)
・名言を削除できる(DELETE)
・名言をランダムに返す(RANDOM)
・名言一覧を返す(SHOW)

〜使ったもの〜
・PHP
・BEAR.Sunday
・SQLite3
・heroku

 

ソースはこちら。herokuでデプロイするために、調整してます。
https://github.com/kin29/bear-work

 

API:https://today-saying-sqlite.herokuapp.com/?mode=show

 

 

これ作るにあたって、わかったこととか後々書こうと思いますー

とりあえず、披露したかっただけです^^

 

WordPressのプラグインを作ってみる。

ソースコードはこちら
https://github.com/kin29/wp-plugin-test/tree/master/admin-header-message

 

プラグインって「ハードル高そう」って思ってました。

まだよくわかってないですが、思ったほど難しくなかったです!

 

参考:

https://wpdocs.osdn.jp/Main_Page

https://hatsuka.info/wordpress/gpl

 

 

コメントを以下のように記載すると、プラグインと認識してくれます。

/**
 * Plugin Name: AdminMessage Maker
 * Plugin URI: https://github.com/kin29/wp-plugin-test/tree/master/admin-header-message
 * Description: You can set your like message in admin-page header.
 * Version: 1.0.0
 * Author: kin29
 * Author URI: https://kin29.info
 * License: GPL2
 */
/*  Copyright 2018 ki29 (email : kin29.com@gmail.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License, version 2, as
	published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

 

 

管理画面ではこんな感じ。

プラグイン詳細

 

 

「有効化」すると、こんななります。

左上に「hello,kin29!」と出てるのがプラグインのしわざです。

プラグインイメージ

 

\ソースの中身/

関数addTestは、WP_Admin_Barクラスの関数add_menuを使って、

idが my-menu のtitileが hello, kin29! のもの追加してます。(見たままw)

idに関しては、my-menuっていうのが既存であるのかと思ってましたが、

idの値はなんでもokでした。

titleの中身は表示させたい言葉はご自由に入れてください。

function addTest($x){
//$x='admin_bar_menu'
 $x->add_menu( array(
    'id' => 'my-menu',
    'title' => 'hello, kin29!'
  ) );
}
add_action('admin_bar_menu', 'addTest');

 

 

\add_action()何しとるん?/

グローバル変数の$wp_filterにキーとバリュー追加してるようですね。

上のコードを例にすると、

$wp_filter[‘admin_bar_menu’]に関数addTest()を追加したようです。

 

wp-include/plugin.phpより

function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
	return add_filter($tag, $function_to_add, $priority, $accepted_args);
}
function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
	global $wp_filter;
	if ( ! isset( $wp_filter[ $tag ] ) ) {
		$wp_filter[ $tag ] = new WP_Hook();
	}
	$wp_filter[ $tag ]->add_filter( $tag, $function_to_add, $priority, $accepted_args );
	return true;
}

 

 

 

\GPLとは?/

コメントアウトにある、License表記ですが、

部分はcodexでは以下のように書いています。

慣例として、標準プラグイン情報の次にプラグインのライセンス情報を書きます。多くのプラグインは WordPress と同じ GPL2、ないし GPL2 互換のライセンス (英文) を用いています。

多くのプラグインに沿って、GPL2と私は書いてます。

GPL=GNU General Public License。フリー(自由)ソフトウェアライセンスの事。WordPressやGithubなどはこのライセンスに属している。コピーライトの逆の「コピーレフト」であり、利用・改変・再配布ができる。GPLで配布したものが、再配布がされるとそれ自身もGPLとなり、自由の保証が広がっていき、良いコードがいろんな人の手で作られるのかなと思います。

 

 

\まとめ/

プラグインは意外と簡単にできる。(物によるが)

プラグイン情報(licenseとか)はちゃんと書こう!

 

変数のスコープ(=有効範囲)

緑化りょくかー

https://github.com/kin29/php

 

そろそろなにか作りたいんですね

だけど、アイデアがないなー

 

今回のお題は

変数のスコープ、有効範囲についてです。

 

 

\登場人物はー?/

・ローカル変数

・グローバル変数

・静的(static)変数

 

コメントつけまくったらすんごーい醜いww

 

コミットコメント

 

▶️ローカル変数

関数内で定義されて、有効範囲はその関数内のみ。

4行目の$aはローカル変数ではない。

  4 $a = 1;
  5 function showLocalNum()
  6 {
  7   //-----ローカル変数 $aのスコープ ここから-----
  8   $a = 2; // ←ローカル変数 $aの定義
  9   print 'ローカル変数 $a: ' . $a . "\n";
 10   //-----ローカル変数 $aのスコープ ここまで-----
 11 }
 12 showLocalNum(); // 2 →ローカル変数 $a
 13 print '4行目の$a: ' . $a . "\n"; //8行目のローカル変数の$aではない。

 

ローカル変数 $a: 2
4行目の$a: 1

 

▶️グローバル変数

関数内外問わず定義され、有効範囲はPHPスクリプト全体

 17 $g = 1;
 18 function showGlobalNum()
 19 {
 20   global $g;
 21   $g++;
 22   print 'グローバル変数 $g: ' . $g . "\n";
 23 }
 24 print '関数showGlobalNum実行前の17行目の$g: ' . $g . "\n"; // 1 まだグローバル変数になってない。
 25 showGlobalNum(); // 2 →グローバル変数 $g
 26 showGlobalNum(); // 3 →グローバル変数 $g
 27 print '関数showGlobalNum実行前後の17行目の$g: ' . $g . "\n"; // 3 グローバル変数 $gになってる

 

関数showGlobalNum実行前の17行目の$g: 1
グローバル変数 $g: 2
グローバル変数 $g: 3
関数showGlobalNum実行前後の17行目の$g: 3

 

▶️静的(static)変数

関数内で定義される。初期化は最初の一回のみ行われ、その後は前の値が残る。

 31 //static $d = 100; //関数外では定義できない
 32 function showStaticNum()
 33 {
 34   static $s = 100; //←ローカル変数 $sの定義
 35   $s++;
 36   print '静的(static)変数 $s: ' . $s . "\n";
 37 }
 38 showStaticNum(); // 101
 39 showStaticNum(); // 102
 40 showStaticNum(); // 103

 

静的(static)変数 $s: 101
静的(static)変数 $s: 102
静的(static)変数 $s: 103

 

 

<まとめ>

ローカル変数しか、あんまり使わんけども。

 

 

requireとincludeの違い

サンプルコードはこちら↓
https://github.com/kin29/php

・requireVsInclude.php

・once.php

 

\ 今回の主人公はー?こちらっ /

・require

・require_once

・include

・include_once

 

 

そもそも上の四つは外部ファイルを参照するときに使います。

..requireとincludeの違い

require と include はほぼ同じだが、失敗した場合の動きが異なる。

require → 致命的なエラーを発生する。スクリプトの処理がそこで止まってしまう。 include → 警告 (E_WARNING) を発するが、スクリプトの処理は続行する。

 

<イメージ>

require …

「君が必要なんだ!だから、君がいないならもうやめてしまおう、

こんなこと。」てきな

 

include…

「お前もくる?あ、どっちでもいいよ?無理なら全然いいから〜、

お前おらんでもできるから。」

てきな。

 

 

※あくまでも個人的なイメージです。

 

 

 

では、require と include を比べて見ましょう。

こんなファイルを用意。requireVsInclude.php

  1 <?php
  2
  3 /**
  4  * 今回比較するもの
  5  * - require
  6  * - include
  7  */
  8
  9 //わざと失敗させる:該当ファイル(notFound.php)がない
 10 echo "---include(Error) START---\n";
 11 include(dirname(__FILE__) . '/notFound.php');
 12 echo "---include(Error) E N D---\n\n";
 13
 14 echo "---include START---\n";
 15 include(dirname(__FILE__) . '/dummy/include.php');
 16 echo "---include E N D---\n\n";
 17
 18 //わざと失敗させる:該当ファイル(notFound.php)がない
 19 echo "---require(Error) START---\n";
 20 require(dirname(__FILE__) . '/notFound.php');
 21 echo "---require(Error) E N D---\n\n";
 22
 23 echo "---require START---\n";
 24 require(dirname(__FILE__) . '/dummy/require.php');
 25 echo "---require E N D---\n\n";

 

いざ、実行!

$ php requireVsInclude.php
---include(Error) START---

Warning: include(/xxxxxx/php/src/notFound.php): failed to open stream: No such file or directory in/xxxxxx/php/src/requireVsInclude.php on line 11

Warning: include(): Failed opening '/xxxxxx/php/src/notFound.php' for inclusion (include_path='.:') in/xxxxxx/php/src/requireVsInclude.php on line 11
---include(Error) E N D---

---include START---
includeしました。
---include E N D---

---require(Error) START---

Warning: require(/xxxxxx/php/src/notFound.php): failed to open stream: No such file or directory in/xxxxxx/php/src/requireVsInclude.php on line 20

Fatal error: require(): Failed opening required '/xxxxxx/php/src/notFound.php' (include_path='.:') in/xxxxxx/php/src/requireVsInclude.php on line 20

 

11行目のincludeで存在しないファイルですとWarningされますが、

処理は続けていますね。

そして、次のinclude処理(15行目)は正しく行われています。

一方で、20行目のrequireは「存在しないファイルをopenできなかった」

とFatalErrorしています。

よって、ここ(20行目)で処理が中止され24行目のrequire処理は実行されませんでした。

 

 

つづいて….  require_onceとinclude_onceを比較します。

こんなファイルを用意。once.php

  1 <?php
  2
  3 /**
  4  * 今回比較するもの
  5  * - require_once
  6  * - include_once
  7  */
  8
  9 //~_onceつかってみる
 10 echo "---require START---\n";
 11 require(dirname(__FILE__) . '/dummy/require.php');
 12 echo "---require E N D---\n\n";
 13
 14 echo "---require_once START---\n";
 15 require_once(dirname(__FILE__) . '/dummy/require.php');
 16 echo "---require_once E N D---\n\n";
 17
 18
 19 echo "---include START---\n";
 20 include(dirname(__FILE__) . '/dummy/include.php');
 21 echo "---include E N D---\n\n";
 22
 23 echo "---include_once START---\n";
 24 include_once(dirname(__FILE__) . '/dummy/include.php');
 25 echo "---include_once E N D---\n\n";

 

いざ、出 陣!

ちなみに

/dummy/require.php がよばれると「requireしました。」をechoします。

/dummy/include.php がよばれると「includeしました。」をechoします。

$ php once.php
---require START---
requireしました。
---require E N D---

---require_once START---
---require_once E N D---

---include START---
includeしました。
---include E N D---

---include_once START---
---include_once E N D---

11行目で一度requireされたので、15行目のrequire_onceでは呼び出されませんでした。

includeでも同様で、

20行目で一度includeされたので、24行目のinclude_onceでは呼び出されませんでした。

 

 

\ まとめ /

・絶対必要なファイルはrequireでよぶ。

何回呼んじゃうか、わからん時はrequrie_once使っとこう。

 

参照(リファレンス)渡しは、ニコイチになる呪文

久々にPHPネタを書きます。

といっても参照渡しって他の言語でもあるかと思いますが、、、長い目でみてください。

Githubにもコミットしてますう。
https://github.com/kin29/php/blob/master/src/passArgument.php

 

 

▶︎参照(リファレンス)渡しとは

引数の渡し方の一つ。
引数の渡し方では、「参照渡し」以外に、
ごく一般的でよく見る普通の引数の渡し方に「値渡し」がある。

 

まず、ごく一般的でよく見る普通の引数の渡し方の

「値渡し」を見ていきます。

/**
 * 数値型を文字列型に変更する
 *
 * @param integer $number
 * @return string $number
 */
function convertString($number)
{
  //return (string)$number;のが冗長ではないが、そこは我慢。
  $number = (string)$number;
  return $number;
}

$a = 1;
convertString($a); 
var_dump($a); //int(1) 返り値を$aに格納していないため、$a = 1のまま

$b = 2;
$b = convertString($b);
var_dump($b); //string(1) "2"

 

 

その後に、「参照渡し」を見てみる。

//PHP5.4.0から仕様変わったやーつー。※今回はPHP5.5を想定
/**
 * 数値型を文字列型に変更する
 *
 * @param integer $number
 * @return string $number
 */
function convertString_reference(&$number)
{
  $number = (string)$number;
  return $number;
}

$c = 3;
//PHP5.4.0以前ではconvertString_reference(&$c)でも呼べる
convertString_reference($c); //$numberと$cがニコイチとなる。
var_dump($c); //string(1) "3"

$d = 4;
//$numberと$dがニコイチ(同等)となる。
$d = convertString_reference($d); 
var_dump($d); //string(1) "4"

参照渡しをすると、ニコイチになれる!

ニコイチってもう古いんかな?昔はやってたからいい例えと思って使ってみたw

参照渡しで渡された引数は、関数内のローカル変数と同等になる。

片方が+1されると、他方も+1される、まさしくニコイチ!

 

 

影響範囲を考えないと使いにくそうで、自から使ったことはまだないですが、

使えるいいタイミング見つけてみたいと思います。

PHP Data Object

 

お久しぶりです。
最近、家の周りで工事が大量にされており騒音がひどくちょっとイライラしております。

 

ではでは、PHPをもっと知ろうのコーナーです!
PHPってmysqlなどのデータベースを操作できますよねー
その仕組みとは?ということで、

PDO = PHP Data Odjects

について知ろうと思います!!!

 

 

先ほども申した通り、PHPでデータベースを扱うためには、

PDO(= PHP Data Odjects)というオブジェクトを使います。

 

これにより

▶︎データベースに接続

▶︎データベース操作(SQLの実行)

を行うことができます。

 

 

▶︎データベース接続 …PDOクラスを使う

https://php.net によると

例1 ドライバ呼び出しにより PDO インスタンスを生成する

/* ドライバ呼び出しを使用して MySQL データベースに接続する */
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';

try {
  $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
  echo 'Connection failed: ' . $e->getMessage();
}

 

ドライバとは?ってなったんで私の中で落としこんだ意味が

ドライバ…データベースを扱うためするためのモジュール(プログラム)

つまりMysqlやPostgreSQL,SQLiteのことですね

 

 

//第一引数でデータベースドライバの種類:データベース名;host名の指定
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';

 

//第二引数でデータベースユーザ名を指定
$user = 'dbuser';

 

//第三引数でデータベースユーザパスを指定
$password = 'dbpass';

 

 

▶︎SQLの実行 …PDOクラス or PDOStatementクラスを使う

ここで疑問を感じたのが、

\PDOStatement::executeとPDO::exec何が違うん?/

ってことです。

 

では、PDOクラスと PDOStatementクラスについて。

https://php.net によると

PDO::exec — SQL ステートメントを実行し、作用した行数を返す

PDO::exec() は SELECT 文からは結果を返しません。 プログラム中で一度だけ発行が必要になる SELECT 文に対しては、 PDO::query() の発行を検討してください。 複数回発行が必要な文については、PDO::prepare() による PDOStatement オブジェクトの準備と PDOStatement::execute() による文の発行を行ってください。

PDO::exec()は実行結果を返すんじゃなくて、行数しか返さないらしい。
そして、プレースホルダーとか使えんぽい。

やってみよう。

テーブルusers
|id|name|score|
|1|taro|0|

 

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$sql ='SELECT * FROM users';
//return 0 ...SELECT 文からは結果を返しません。
print_r($db->exec($sql));

 

//プレースホルダーを使ってみる

使いようがなかった。。

//プレースホルダーではないが、、、こうすることはできる(当たり前)

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$whereVal = 1;
$sql ='SELECT * FROM users WHERE id ='. $whereVal;
//return 0 ...SELECT 文からは結果を返しません。
print_r($db->exec($sql));

 

 

PDOStatement::execute — プリペアドステートメントを実行する

返り値

成功した場合に TRUE を、失敗した場合に FALSE を返します。

プリペアドステートメント….直訳で準備陳述。

これも実行するするだけ。成功したか失敗したかを返す。
一方、PDOStatement::executeは
PDOStatement::prepareでSQLステートメントをセットして、プレースホルダーとか使えるぽい。

 

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$sql ='SELECT * FROM users';
$stmt = $db->prepare($sql);

//return 1(=true) ...成功!
print_r($stmt->execute());

 

//プレースホルダーを使ってみる

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$sql ='SELECT * FROM users WHERE id = :id';
$stmt = $db->prepare($sql);

//さっきと同じ return 1(=true) ...成功!
print_r($stmt->execute(array(':id' => 1)));

 

 

 

結果が欲しいのに!ってときはこれ。

PDO::query

PDO::query — SQL ステートメントを実行し、結果セットを PDOStatement オブジェクトとして返す

$db = new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD);
$sql ='SELECT * FROM users';
foreach ($db->query($sql) as $row) {

  print('id: ' . $row['id'] . '<br>');
  print('name: ' . $row['name'].'<br>');
  print('score: ' . $row['score'].'<br>');

}

 

<まとめ>

・PDOをサクッと直接的にsql実行できる。

・PDOStatementはプレースホルダーとか使って計画的にsql実行できる。

・ 結果が欲しいときはPDO::query