• 締切
  • すぐに回答を!

mysqlから取得した配列をカンマで分割して配列に

  • 質問No.8206281
  • 閲覧数422
  • ありがとう数1
  • 回答数6

お礼率 37% (3/8)

mysqlに登録されたデータを添字配列で受け取り、配列の中のデータを区切り文字で分割して
新たな配列を作りたいのですが、どのようにすれば良いでしょうか?

テーブル名:tableA
|s_date|staff_id|   cell01  |cell02|~|   cell200   |
├──-┼───-┼──────┼──-┼─┼───────┤
|08-04|  002 |10:35,会議室,1| -  |~|19:40,フロアB,3 |
├──-┼───-┼──────┼──-┼─┼───────┤

テーブル名:tableB
|staff_num|staff_name| 所属 |
├────┼────-┼───┤
|  002  | A山A男 |A支店 |
├────┼────-┼───┤


$sql = "SELECT * FROM tableA JOIN tableB ON tableA.staff_id = tableB.staff_num WHERE s_date = '$today' ";
$rst = mysql_query($sql , $con);
if($rst){
while($col = mysql_fetch_row($rst)){

cell01~cell200の結果を順番に出力したいので$col[15]と、添え字で取り出せる様にmysql_fetch_rowにしました。

for ($i = 2, $max = count($col); $i< $max - 3; $i++){
echo'<dd>'.$col[$i].'</dd>'."\n";

このままだと出力結果は下記になりますが

<dd>10:35,会議室,1</dd>

$col[$i]の中身をカンマで分割して利用したいと思っています。

$col[0][time] → 10:30   $col[200][time] → 19:40
$col[0][place] → 会議室   $col[200][place] → フロアB
$col[0][flag] → 1      $col[200][flag] → 3

echo'<dd class="style'.$col[$i][flag].'">場所:'.$col[$i][time].'開始時間:'.$col[$i][time].'</dd>'."\n";

この様な感じで出力されるのが理想です。

<dd class="style1">場所:会議室 開始時間:10:35</dd>

違う書き方でも結果が同じであれば、それでも構いません。
少しでもアドバイスをいただければ助かります。よろしくお願い致します。

回答 (全6件)

  • 回答No.6

ベストアンサー率 51% (3827/7415)

データの持ち方がよくないように感じます
こんな感じでデータを持てばよいのでは?

create table tableA(s_date date,staff_id int,cell int,jikan time,basho varchar(30),flag int,unique(s_date,staff_id,cell));
insert into tableA values
('2013-08-04',2,1,'10:35','会議室',1)
,('2013-08-04',2,200,'19:40','フロアB',3)
,('2013-08-04',3,1,'10:40','フロアB',2)
,('2013-08-04',3,200,'19:40','フロアA',1)
,('2013-08-05',2,1,'10:20','会議室',1);

これを一覧で得るのであればこんな感じ?
select s_date,staff_id
,group_concat(if(cell=1,txt,null)) as cell001
,group_concat(if(cell=2,txt,null)) as cell002
・・・
,group_concat(if(cell=200,txt,null)) as cell200
from(
select s_date,staff_id,cell,concat(hour(jikan),':',minute(jikan),',',basho,',',flag) as txt
from tableA
) sub
group by s_date,staff_id
  • 回答No.5

ベストアンサー率 77% (407/525)

訂正(何度もすみません)

____switch (true) {
________case !isset($_REQUEST['date']):
________case !is_string($date = $_REQUEST['date']):
____________throw new Exception('日付を指定してください');
________case !($link = @mysql_connect('localhost', $dbuser, $dbpass)):
____________throw new Exception('MySQL接続失敗');
________case !mysql_select_db($dbname, $link):
________case !mysql_set_charset('utf8', $link):
________case !($result = mysql_query(sprintf($sql, mysql_real_escape_string($date, $link)), $link)):
____________throw new Exception(mysql_error($link));
____}

mysql_connectに失敗したときはmysql_errorは使えないのでこうするしかないです。
  • 回答No.4

ベストアンサー率 77% (407/525)

mysql関数を使えば早く書けるとか全然そんなことありませんが・・・

mysql関数バージョン
http://ideone.com/lxE1bl

<?php

try {
____
____$dbname = '';
____$dbuser = '';
____$dbpass = '';
____$sql = 'SELECT * FROM tableA JOIN tableB ON tableA.staff_id = tableB.staff_num WHERE s_date = %s';
____
____switch (true) {
________case !isset($_REQUEST['date']):
________case !is_string($date = $_REQUEST['date']):
____________throw new Exception('日付を指定してください');
________case !($link = @mysql_connect('localhost', $dbuser, $dbpass)):
________case !mysql_select_db($dbname, $link):
________case !mysql_set_charset('utf8', $link):
________case !($result = mysql_query(sprintf($sql, mysql_real_escape_string($date, $link)), $link)):
____________throw new Exception(mysql_error($link));
____}
____
____$rows = array();
____while ($tmp = mysql_fetch_assoc($result)) {
________$rows[] = $tmp;
____}

____array_walk_recursive($rows, function (&$v, $k) {
________if (strpos($k, 'cell') !== 0) {
____________return;
________}
________$values = explode(',', $v, 3);
________if (!isset($values[2])) {
____________$values = array_fill(0, 3, '-');
________}
________$keys = array('time', 'place', 'flag');
________$v = array_combine($keys, $values);
____});
____
} catch (Exception $e) {
____
____$error = htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
____
}

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<?php if (isset($error)): ?>
<p><?=$error?></p>
<?php elseif (!$rows): ?>
<p>データが見つかりませんでした</p>
<?php else: ?>
<?php foreach ($rows as $row): ?>
<table border>
<caption><?=$row['staff_name']?>(<?=$row['s_date']?>)</caption>
<tr>
<th>場所</th>
<th>開始時間</th>
</tr>
<?php foreach (array_slice($row, 2, -3) as $r): ?>
<?php if ($r['time'] === '-') { continue; }?>
<tr class="style<?=$r['flag']?>">
<td><?=$r['place']?></td>
<td><?=$r['time']?></td>
</tr>
<?php endforeach; ?>
</table>
<?php endforeach; ?>
<?php endif; ?>
</body>
</html>
補足コメント
nekocue

お礼率 37% (3/8)

何度も有難うございます!
質問用に簡略化したソースを提示しましたが、他の部分もかなり量があるので、PDOの使い方を調べながら書く時間が無いのです。すみません。
今まであまりforeachは使ってなかったので思いつきませんでした。これから回答を参考に書き直してみます。有難うございました。
投稿日時:2013/08/06 01:07
  • 回答No.3

ベストアンサー率 44% (126/282)

補足コメント
nekocue

お礼率 37% (3/8)

if($shop){
list($s_name,$s_add,$s_tell) = explode(':', $shop);
}
今まで↑のような感じで使っていましたが、今回はフィールド数が膨大でcell01~cell200まで200個あります。
中に入るデータ形式は同じなので、纏めて分割する方法が知りたいのです。
投稿日時:2013/08/05 13:31
  • 回答No.2

ベストアンサー率 77% (407/525)

【訂正】

http://ideone.com/z0qcAt

<?php

try {
____
____switch (true) {
________case !isset($_REQUEST['date']):
________case !is_string($date = $_REQUEST['date']):
____________throw new Exception('日付を指定してください');
____}
____
____$dbname = '';
____$dbuser = '';
____$dbpass = '';
____
____$pdo = new PDO("mysql:dbname={$dbname};host=localhost;charset=utf8", $dbuser, $dbpass);
____$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
____
____$sql = 'SELECT * FROM tableA JOIN tableB ON tableA.staff_id = tableB.staff_num WHERE s_date = ?';
____$stmt = $pdo->prepare($sql);
____$stmt->execute(array($date));
____$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

____array_walk_recursive($rows, function (&$v, $k) {
________if (strpos($k, 'cell') !== 0) {
____________return;
________}
________$values = explode(',', $v, 3);
________if (!isset($values[2])) {
____________$values = array_fill(0, 3, '-');
________}
________$keys = array('time', 'place', 'flag');
________$v = array_combine($keys, $values);
____});
____
} catch (Exception $e) {
____
____$error = htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
____
}

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<?php if (isset($error)): ?>
<p><?=$error?></p>
<?php elseif (!$rows): ?>
<p>データが見つかりませんでした</p>
<?php else: ?>
<?php foreach ($rows as $row): ?>
<table border>
<caption><?=$row['staff_name']?>(<?=$row['s_date']?>)</caption>
<tr>
<th>場所</th>
<th>開始時間</th>
</tr>
<?php foreach (array_slice($row, 2, -3) as $r): ?>
<?php if ($r['time'] === '-') { continue; }?>
<tr class="style<?=$r['flag']?>">
<td><?=$r['place']?></td>
<td><?=$r['time']?></td>
</tr>
<?php endforeach; ?>
</table>
<?php endforeach; ?>
<?php endif; ?>
</body>
</html>


【動作テスト】

http://ideone.com/CCdqen
  • 回答No.1

ベストアンサー率 77% (407/525)

・もう非推奨のmysql関数を使うのはやめましょう。PDOを推奨します。
・JOINしてるのにtableBのデータを利用するコードが見当たりませんが、他で使うものとして考えます。
・PHPバージョン5.4以上と仮定します。

http://ideone.com/th1lRa

<?php

try {
____
____switch (true) {
________case !isset($_REQUEST['date']):
________case !is_string($date = $_REQUEST['date']):
____________throw new Exception('日付を指定してください');
____}
____
____$dbname = '';
____$dbuser = '';
____$dbpass = '';
____
____$pdo = new PDO("mysql:dbname={$dbname};host=localhost;charset=utf8", $dbuser, $dbpass);
____$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
____
____$sql = 'SELECT * FROM tableA JOIN tableB ON tableA.staff_id = tableB.staff_num WHERE s_date = ?';
____$stmt = $pdo->prepare($sql);
____$stmt->execute(array($date));
____$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
____
____array_walk_recursive($rows, function (&$v, $k) {
________if (strpos($k, 'cell') !== 0) {
____________return;
________}
________$values = explode(',', $v, 3);
________$keys = array('time', 'place', 'flag');
________$v = array_combine($keys, $values);
____});
____
} catch (Exception $e) {
____
____$error = htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
____
}

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<?php if (isset($error)): ?>
<p><?=$error?></p>
<?php elseif (!$rows): ?>
<p>データが見つかりませんでした</p>
<?php else: ?>
<table>
<?php foreach ($rows as $r): ?>
<tr class="style<?=$r['flag']?>">場所:<?=$r['place']?> 開始時間<?=$r['time']?></tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
</body>
</html>
お礼コメント
nekocue

お礼率 37% (3/8)

有難うございます。
PDOを使うべきなのは存じてますが、今回はとにかく早く作るようにせっつかれていますので取り敢えずmysql関数でいく予定です。
いずれはPDOで書き直さなければならないので、その際に参考にさせていただきます。
投稿日時:2013/08/05 07:15
関連するQ&A

その他の関連するQ&Aをキーワードで探す

ページ先頭へ