関連記事: http://qiita.com/muzudho1/items/51f2ec976377625ff0f1
グーグル・スプレッドシート、PHP、MySQL の連携は前の記事で でけたのだった。
今回やりたいこと
日付と時刻 | プレイヤー名 | クリアタイム |
---|---|---|
2017/04/11 19:34 | むすでょ | 24:59'637 |
なるほど、こんな仕様書は 飛んでくるだろう。
グーグル・スプレッドシートなら、これはできる……が 微妙に つまづく。
難点
24:59'637 を PHP で「24:59」と「637」に分けると、24分59秒 637 ミリ秒ではなく、24時59分00秒 637 ミリ秒だ。分かる。
時:分 ではなく 分:秒 だろ、「それぐらい分かってくれよ」を PHP に組み込む必要があるだろう。しかし世の中には 分秒表記が無いのだろうか?
「「”」や「’」を使ったタイム表記の例を教えてくだ…」YAHOO!JAPAN 知恵袋
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q136411458
なるほど、角度表記を使えば 24'59''637 で すっきり している。でもお客さんは「24:59'637で分かってくれよ」と言うだろうから、文字数が5文字以下なら頭に「00:」を付けるなどして 対応しよう。
さくっと済ませて 何が問題なのかというと、1年後に「分:秒 ではなく 時:分 だろ、お前は そんなことも分からんのか!」とメールが飛んでくる可能性があるんだが、現時点でも 1年前からメールが飛んでくる可能性はある。タイムマシン・キャッチボールでもするか。
日付と時刻
2017/04/11 19:34
これは そのまま打ち込めばいい。
内部的には
2017/04/11 19:34:00
のような形式で持っているが、見た目は 入力したまま保たれるようだ。
ツールバーの「123」と描かれたボタンから
[表示形式の詳細設計] - [表示形式の詳細設計] - [その他の日付や時刻の形式...]
と進むと、秒は要らない、とか がっちり 指定できるんだが、
仕様書通りにぴっちり作ると 実践では顧客から1年後ぐらいに「余計なことをしてくれた」と言われる可能性がある。
“サブマリン余計なことをしてくれた” を食らうぐらいなら
グーグル・スプレッドシートの「自動」な挙動に任せた平凡なつくりにしておこう。
プレイヤー名
4文字しか入らない、といった制限を設けたいことがあるだろう。
マクロ(グーグル・アプリ・スクリプト)を書けば 入力を弾くことはできそうなんだが、
要件定義では そんなことは やって欲しくはなく、データベースを入れるときに 問答無用で 切り落せばよさそうだ。
PHP側で切り落とす 方法を あとで記述する。
クリアタイム
ツールバーの「123」と描かれたボタンから
[表示形式の詳細設計] - [表示形式の詳細設計] - [その他の日付や時刻の形式...]
と進み、
最初から入っている 年、月、日は クリックして削除を選び、
新たに 分、秒、ミリ秒 を追加すること。
このとき、ミリ秒は 精度を 1/10、1/100、1/1000 で指定できる。1/1000 を選ぶ。
<<<<<<< HEAD
テスト用のデータベースを用意しよう
MySQL で 1000ミリ秒単位のデータを持つ方法が分からなかった。
精度が 3ミリ秒……、と書かれている記事もあり、1ミリ秒じゃなきゃ やだい。
別途、ミリ秒を持つ列を作った方がいいのか?
TIME_ATTACK テーブル
DATE | PLAYER | CLEARTIME | CLEARTIME_MS |
---|---|---|---|
2017/04/11 19:34 | むすでょ | 24:59 | 637 |
TIME_ATTACK テーブル 列定義
列名 | 型 | サイズ |
---|---|---|
DATE | DATE | |
PLAYER | VARCHAR | 4 |
CLEARTIME | TIME | |
CLEARTIME_MS | SMALLINT |
PhpMyAdmin でフォーム入力していけばいい気もするんだが、SQLを流そう。
-- phpMyAdmin SQL Dump
-- version 4.0.10.15
-- http://www.phpmyadmin.net
--
-- ホスト: localhost
-- 生成日時: 2017 年 4 月 11 日 19:13
-- サーバのバージョン: 5.1.73
-- PHP のバージョン: 5.6.29
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- データベース: `★データベース名`
--
-- --------------------------------------------------------
--
-- テーブルの構造 `RENSYU_TIME_ATTACK`
--
CREATE TABLE IF NOT EXISTS `RENSYU_TIME_ATTACK` (
`DATE` date NOT NULL,
`PLAYER` varchar(4) NOT NULL,
`CLEARTIME` time NOT NULL,
`CLEARTIME_MS` smallint(6) NOT NULL COMMENT 'ミリ秒 0~999'
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Qiita記事用';
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
データベースを選択してから、SQL メニューを選んで クエリーを貼り付けて[実行]ボタンを押す。
EDIT_REQUEST
POST送信
このプログラムは 前にも書いた。
グーグルスプレッドシートから [スコア送信] - [スコア送信実行] を選ぶと、スプレッドシートの内容をサーバー側に送るものだ。
参考記事: 「Tool] Google SpreadSheetでマクロを使って作業を効率化」http://www.yoheim.net/blog.php?q=20130412
// 参考記事: 「Tool] Google SpreadSheetでマクロを使って作業を効率化」http://www.yoheim.net/blog.php?q=20130412
// 起動時処理
function onOpen() {
// メニューバーにカスタムメニューを追加
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [
{name : "スコア送信実行" , functionName : "submitRanking"},
];
spreadsheet.addMenu("スコア送信", entries);
}
// メニューから実行する
function submitRanking(){
//----------
// 定数
//----------
// ヘッダー、データの開始列(先頭が1)
var HEADER_COLUMN_START_INDEX = 1;
// ヘッダー行
var HEADER_ROW_INDEX = 1;
// データの開始行
var DATA_ROW_START_INDEX = 2;
// Bookやシートを取得する
var sheet = SpreadsheetApp.getActiveSheet();
var ss = SpreadsheetApp.getActiveSpreadsheet();
// ヘッダ情報を取得する
var headers = [],
headerColumnPos = HEADER_COLUMN_START_INDEX;
while (true) {
// sheet.getRangeでRangeオブジェクトを取得できます。
var val = sheet.getRange(HEADER_ROW_INDEX, headerColumnPos++).getValue();
if (!val) {break;}
headers.push(val);
}
// ログ出力はこんな感じ。
// ScriptエディタのメニューバーのView -> Logsで確認できます。
Logger.log(headers);
// 1行ずつ読み込みます。
var rowIndex = DATA_ROW_START_INDEX;
var rowData = [];
while (true) {
// if no data, exit loop.
var checkVal = sheet.getRange(rowIndex, 1).getValue();
if (!checkVal) {
break;
}
// cerate data row by row
var columnPos = HEADER_COLUMN_START_INDEX;
var valueObject = {};
for (var i = 0, len = headers.length; i < len; i++) {
var key = headers[i];
var value = sheet.getRange(rowIndex, columnPos++).getValue();
valueObject[key] = value;
}
rowData.push(valueObject);
// next row.
rowIndex++;
}
// Logger.log(rowData);
// JSObject to JSON
var json = JSON.stringify(rowData);
Logger.log(json);
// POST送信のテスト
var formData = {
'datas': json
};
var options = {
'method' : 'post',
'payload' : formData
};
UrlFetchApp.fetch("http://★サイトアドレス/insert4.php", options);
// メッセージボックスにJSONを表示して終了します
Browser.msgBox(json);
}
テスト用のデータベースを用意しよう
MySQL で 1000ミリ秒単位のデータを持つ方法が分からなかった。
精度が 3ミリ秒……、と書かれている記事もあり、1ミリ秒じゃなきゃ やだい。
別途、ミリ秒を持つ列を作った方がいいのか?
RENSYU_TIME_ATTACK テーブル
PLAY_DATE | PLAYER | CLEARTIME | CLEARTIME_MS |
---|---|---|---|
2017/04/11 19:34 | むすでょ | 24:59 | 637 |
- 重複レコードを削除したかったので、あとでID列を増やした
- 列名に DATE は避けて PLAY_DATEとか適当に付けた
RENSYU_TIME_ATTACK テーブル 列定義
列名 | 型 | サイズ |
---|---|---|
PLAY_DATE | DATE | |
PLAYER | VARCHAR | 4 |
CLEARTIME | TIME | |
CLEARTIME_MS | SMALLINT |
PhpMyAdmin でフォーム入力していけばいい気もするんだが、SQLを流そう。
-- phpMyAdmin SQL Dump
-- version 4.0.10.15
-- http://www.phpmyadmin.net
--
-- ホスト: localhost
-- 生成日時: 2017 年 4 月 11 日 19:13
-- サーバのバージョン: 5.1.73
-- PHP のバージョン: 5.6.29
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- データベース: `★データベース名`
--
-- --------------------------------------------------------
--
-- テーブルの構造 `RENSYU_TIME_ATTACK`
--
CREATE TABLE IF NOT EXISTS `RENSYU_TIME_ATTACK` (
`PLAY_DATE` date NOT NULL,
`PLAYER` varchar(4) NOT NULL,
`CLEARTIME` time NOT NULL,
`CLEARTIME_MS` smallint(6) NOT NULL COMMENT 'ミリ秒 0~999'
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Qiita記事用';
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
データベースを選択してから、SQL メニューを選んで クエリーを貼り付けて[実行]ボタンを押す。
これで テーブルの準備はおっけ!
サーバー側の PHP
データを送信できたか確かめるためのページ
table1a1.php
<?php
// 参考: 「[PHP] mysqli使い方まとめ(MySQL接続~SELECT実行まで)」 http://qiita.com/yasumodev/items/bd2ba476f31804d527d3
// mysqliクラスのオブジェクトを作成
$mysqli = new mysqli('localhost', '★DBユーザー名', '★パスワード', '★DB名');
if ($mysqli->connect_error) {
echo $mysqli->connect_error;
exit();
} else {
$mysqli->set_charset('utf8');
}
// ここにDB処理いろいろ書く(後述)
// 完成済みのSELECT文を実行する
$query = 'SELECT PLAY_DATE, PLAYER, CLEARTIME, CLEARTIME_MS FROM RENSYU_TIME_ATTACK';
if ($result = $mysqli->query($query)) {
// 連想配列を取得
while ($row = $result->fetch_assoc()) {
echo $row['PLAY_DATE'] . ', ' . $row['PLAYER'] . ', ' . $row['CLEARTIME'] . ', ' . $row['CLEARTIME_MS'] . '<br />' . "\n";
}
// 結果セットを閉じる
$result->close();
}
// DB接続を閉じる
$mysqli->close();
開発中に確認するだけ用なんで、ぺぺっと作る。
長い文字列の末尾を、文字数で切り捨てるには?
// 注意: 半角1文字は1、全角1文字は2 とカウントされる
$PLAYER = mb_strimwidth( $datas[0]['プレイヤー名'], 0, 8, '', 'UTF-8' );
こんなので いいのだろうか?
もっといいのがあった。
// 4文字で切り落とし
$PLAYER = mb_substr( $record['プレイヤー名'], 0, 4 );
文字をスプリットするには?
クリアタイム |
---|
24:59'637 |
を、
CLEARTIME | CLEARTIME_MS |
---|---|
24:59 | 637 |
に分けるにはどうすればいいのか? PHPにはスプリット関数があるんだろうか?
$clear_time = $datas[0]['クリアタイム'];
$tokens = explode("'", $clear_time);
$CLEARTIME = $tokens[0];
$CLEARTIME_MS = $tokens[1];
こんなので いいのだろうか?
インサート用のPHP
下のコードは だいぶ サボっていて、1行目しか送信しない。 $datas[0] と書いてあるところを改造してほしい。あとで改造後のを載せる。
insert4.php
<?php
// ヒント: このファイルのエンコーディングを UTF-8 BOM有り にすること。
// 参考 : http://qiita.com/yasumodev/items/bd2ba476f31804d527d3
if(isset($_POST['datas'])){
$datas =json_decode( $_POST['datas'], true);
// mysqliクラスのオブジェクトを作成
$mysqli = new mysqli('localhost', '★DBユーザー名', '★パスワード', '★DB名');
if ($mysqli->connect_error) {
echo $mysqli->connect_error;
exit();
} else {
$mysqli->set_charset("utf8");
}
// ここにDB処理いろいろ書く
// ひな型をもとにステートメントハンドルを取得する
$sql = "INSERT INTO RENSYU_TIME_ATTACK (PLAY_DATE, PLAYER, CLEARTIME, CLEARTIME_MS) VALUES (?, ?, ?, ?)";
if ($stmt = $mysqli->prepare($sql)) {
// 条件値をSQLにバインドする
// bind_param の第1引数 "is" は後続のデータ型を表します。
// i=integer、s=string、d=double、b=blob など。DATE型は s で良いみたいです。
// また下記のように値を引数内に直書きすることはできません。
// 誤)$stmt->bind_param("is", 123, "hanako");
$PLAY_DATE = $datas[0]['日付と時刻'];
// 4文字で切り落とし
$PLAYER = mb_substr( $record['プレイヤー名'], 0, 4 );
// 12:34'567 と入っていれば 12分34秒567ミリ秒 とする。12時34分ではない。
$clear_time = $datas[0]['クリアタイム'];
$tokens = explode("'", $clear_time);
$CLEARTIME = $tokens[0];
if(5==mb_strlen($CLEARTIME)){
// 00:00 形式と予想して、頭に 00: を付けることで 00:00:00 にする
$CLEARTIME = '00:' . $CLEARTIME;
}
$CLEARTIME_MS = $tokens[1];
// 注意: 第一引数で型の指定も忘れないこと
$stmt->bind_param("sssi", $PLAY_DATE, $PLAYER, $CLEARTIME, $CLEARTIME_MS);
// 実行
$stmt->execute();
$stmt->close();
}
// DB接続を閉じる
$mysqli->close();
}
else
{
echo 'error: post data not found.' . "\n";
}
?, ?, ?, ? の数を合わせたり、 "sssi" とか書いたりすることを忘れていることに 気づきにくかった。
じゃあ、これを タイムが短い順に表示するには?
table7.php
<?php
// ヒント: このファイルのエンコーディングを UTF-8 BOM有り にすること。
// 参考: 「[PHP] mysqli使い方まとめ(MySQL接続~SELECT実行まで)」http://qiita.com/yasumodev/items/bd2ba476f31804d527d3
// 参考: 「mysqlユーザーのためのmysqliラッパー」http://qiita.com/taro_3000/items/f9db8f816cf3837b59b9
// 参考: 「PHPで自分のファイル名を取得する方法」http://negimemo.net/1705
// 参考: 「<テーブル> * テーブル・セルにスクロールバーをつける *」http://kowaza.boo.jp/03table/table-07-0scroll.html
// mysqliクラスのオブジェクトを作成
$mysqli = new mysqli('localhost', '★DBユーザー名', '★パスワード', '★DB名');
if ($mysqli->connect_error) {
echo $mysqli->connect_error;
exit();
} else {
$mysqli->set_charset("utf8");
}
// ここにDB処理いろいろ書く
//----------
// テーブル表示
//----------
$query = 'SELECT PLAY_DATE, PLAYER, CLEARTIME, CLEARTIME_MS FROM RENSYU_TIME_ATTACK ORDER BY CLEARTIME, CLEARTIME_MS DESC';
if ($result = $mysqli->query($query)) {
?>
<div style="height:90px; width:300px; overflow-y:scroll;">
<table>
<?php
// 連想配列を取得
while ($row = $result->fetch_assoc()) {
echo '<tr><td>' . $row['PLAY_DATE'] . '</td><td>' . $row['PLAYER'] . '</td><td>' . $row['CLEARTIME'] . '</td><td>' . $row['CLEARTIME_MS'] . '</td></tr>' . "\n";
}
// 結果セットを閉じる
$result->close();
?>
</table>
</div>
<?php
}
else
{
echo 'error: query failuer.';
}
// DB接続を閉じる
$mysqli->close();
これでいける。
とはいえ、スプレッド・シートに記入されている全行を 送信したいだろう
毎回、重複する 全行 を送信するのが シンプルな実装だし、仕事とあらば そんなプログラムでも組む。
その代わり MySQL は重複するレコードを マージか、弾くか してくれないだろうか?
「MySQLで重複する行を削除する」Qiita
http://qiita.com/aosho235/items/d748dcb6386d8ce75604
なんか 麺3玉スーパー特盛ラーメンを食べたあとに 胃袋から2玉吐き出せば ラーメン1玉分食べたに等しい、と言った感じのツジツマの合わせ方だ。
ID 列があると クエリー1回 で済むのか。じゃあ ID 列を付けよう。
ALTER TABLE `RENSYU_TIME_ATTACK` ADD `ID` INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;
insert4.php の DBを切断する前のあたりに追記。あとで全部載せる。
//----------------------------------------
// ID列以外が重複しているレコードは、1つを残して削除する
//----------------------------------------
$query = "DELETE FROM RENSYU_TIME_ATTACK WHERE id NOT IN (SELECT min_id from (SELECT MIN(id) min_id FROM RENSYU_TIME_ATTACK GROUP BY PLAY_DATE, PLAYER, CLEARTIME, CLEARTIME_MS) tmp)";
if ($result = $mysqli->query($query)) {
// 成功時
// 結果セットを閉じる
$result->close();
}
これでどうか?
ヘッダーを除く、全行送信する
insert4.php
<?php
// ヒント: このファイルのエンコーディングを UTF-8 BOM有り にすること。
// 参考: 「[PHP] mysqli使い方まとめ(MySQL接続~SELECT実行まで)」http://qiita.com/yasumodev/items/bd2ba476f31804d527d3
// 参考: 「MySQLで重複する行を削除する」http://qiita.com/aosho235/items/d748dcb6386d8ce75604
if(isset($_POST['datas'])){
$datas =json_decode( $_POST['datas'], true);
// mysqliクラスのオブジェクトを作成
$mysqli = new mysqli('localhost', '★DBユーザー名', '★パスワード', '★DB名');
if ($mysqli->connect_error) {
echo $mysqli->connect_error;
exit();
} else {
$mysqli->set_charset("utf8");
}
// ここにDB処理いろいろ書く
foreach ($datas as &$record) {
// ひな型をもとにステートメントハンドルを取得する
$sql = "INSERT INTO RENSYU_TIME_ATTACK (PLAY_DATE, PLAYER, CLEARTIME, CLEARTIME_MS) VALUES (?, ?, ?, ?)";
if ($stmt = $mysqli->prepare($sql)) {
// 条件値をSQLにバインドする
// bind_param の第1引数 "is" は後続のデータ型を表します。
// i=integer、s=string、d=double、b=blob など。DATE型は s で良いみたいです。
// また下記のように値を引数内に直書きすることはできません。
// 誤)$stmt->bind_param("is", 123, "hanako");
$PLAY_DATE = $record['日付と時刻'];
// 注意: 半角1文字は1、全角1文字は2 とカウントされる
$PLAYER = mb_strimwidth( $record['プレイヤー名'], 0, 8, '', 'UTF-8' );
// 4文字で切り落とし
$PLAYER = mb_substr( $record['プレイヤー名'], 0, 4 );
// 12:34'567 と入っていれば 12分34秒567ミリ秒 とする。12時34分ではない。
$clear_time = $record['クリアタイム'];
$tokens = explode("'", $clear_time);
$CLEARTIME = $tokens[0];
if(5==mb_strlen($CLEARTIME)){
// 00:00 形式と予想して、頭に 00: を付けることで 00:00:00 にする
$CLEARTIME = '00:' . $CLEARTIME;
}
$CLEARTIME_MS = $tokens[1];
// 注意: 第一引数で型の指定も忘れないこと
$stmt->bind_param("sssi", $PLAY_DATE, $PLAYER, $CLEARTIME, $CLEARTIME_MS);
// 実行
$stmt->execute();
$stmt->close();
}
}
//----------------------------------------
// ID列以外が重複しているレコードは、1つを残して削除する
//----------------------------------------
$query = "DELETE FROM RENSYU_TIME_ATTACK WHERE id NOT IN (SELECT min_id from (SELECT MIN(id) min_id FROM RENSYU_TIME_ATTACK GROUP BY PLAY_DATE, PLAYER, CLEARTIME, CLEARTIME_MS) tmp)";
if ($result = $mysqli->query($query)) {
// 成功時
// 結果セットを閉じる
$result->close();
}
// DB接続を閉じる
$mysqli->close();
}
else
{
echo 'error: post data not found.' . "\n";
}
3行、4行 程度では 全レコード送信しても 気にならない。
よし。
文字数で切り出し
「[PHP] 文字数単位で文字を切り出す」PHPちょこっとリファレンス
https://php.programmer-reference.com/php-mb_substr/
mb_strimwidth だと 全角1文字は2文字分のカウントをされるんだが、mb_substr を使うと 全角1文字も1文字カウントなのか?
スタイルの外出し
table.css
div.table_container
{
display : inline-block;
height : 285px;
overflow-y: scroll;
}
こう書いておいて、
table.php
<div class="table_container">
テーブルを囲んでいたdivタグのstyle属性をclass属性に変更。
また、table.php の末尾のデータベースを切断した後あたりに次のように書く。
// DB接続を閉じる
$mysqli->close();
//----------------------------------------
// <body>部で後からスタイルシート読込指定
//----------------------------------------
?>
<script type="text/javascript">
addOnload(function(){
var linkElement = document.createElement( "link" );
linkElement.setAttribute( "rel" ,"stylesheet" );
linkElement.setAttribute( "type" ,"text/css" );
linkElement.setAttribute( "href" ,"./table.css" );
document.getElementsByTagName( "head" )[0].appendChild( linkElement );
});
// onloadイベントを追加する
function addOnload(func)
{
try {
window.addEventListener("load", func, false);
} catch (e) {
// IE用
window.attachEvent("onload", func);
}
}
</script>
参考記事: 「EXORK.JP」http://exork.sakura.ne.jp/140806/?p=300
参考記事: 「ビジネスマンの徹底パソコン奮闘サイト」http://pcrice.blog129.fc2.com/blog-entry-11.html
タイムの表示
現状、列の中身をそのまま表示しているので、タイムの表示が
日付と時刻 | クリアタイム |
---|---|
2017-04-11 | 01:26:00 747 |
となってしまっている。本当は次のように表示したい。
日付と時刻 | クリアタイム |
---|---|
2017/04/11 23:42:30 | 1:26'747 |
- PHPで 書式指定は どうやるのだろうか。
- ミリ秒も、3桁表示しないと 1 ミリ秒が '1 では 100ミリ秒になってしまう。
「date」php
http://php.net/manual/ja/function.date.php
「DateTime クラスのまとめメモ」Qiita
http://qiita.com/re-24/items/c3ed814f2e1ee0f8e811
こんな風にした。
// 連想配列を取得
while ($row = $result->fetch_assoc()) {
$PLAY_DATE_1 = new DateTime( $row['PLAY_DATE'] );
$CLEARTIME_1 = new DateTime( $row['CLEARTIME'] );
// 「時:分:秒」を取得し、先頭が「00:」なら、それを省く
$ji_fun_byo = $CLEARTIME_1->format('H:i:s');
if(0===strpos($ji_fun_byo, '00:')){
$ji_fun_byo = mb_substr( $ji_fun_byo, 3 );
}
echo '<tr><td>' . $PLAY_DATE_1->format('Y/m/d H:i') . '</td><td>' . $row['PLAYER'] . '</td><td>' . $ji_fun_byo . "'" . str_pad($row['CLEARTIME_MS'], 3, 0, STR_PAD_LEFT) . '</td></tr>' . "\n";
}
参考: 「【PHP】文字列の一致や、文字列を含むかどうかを判定」http://thesaibase.com/php/strstr
参考: 「PHPで0埋めをする2つの方法- sprintf関数とstr_pad関数」http://wp.tech-style.info/archives/582
不具合の対応
00:00 だけでなく、 0:00 のケースもあった。
if(mb_strlen($CLEARTIME) < 6){
// 00:00 または 0:00 形式と予想して、頭に 00: を付けることで 00:00:00 にする
じゃあ、データを入力する方も こうか?
// '1 と入っていれば 1ミリ秒 ではなく 100ミリ秒
$CLEARTIME_MS = str_pad($tokens[1], 3, 0, STR_PAD_RIGHT);
あと前の記事なんだが、
$query = 'SELECT DISTINCT WEIGHT FROM TAMESI1 ORDER BY WEIGHT';
if ($result = $mysqli->query($query)) {
if(0 < $result->num_rows){
echo '<a href="./' . basename($_SERVER['PHP_SELF']) . '">全て</a> '. "\n";
}
絞り込み条件を付けない場合のリンクも出しておきたい。