質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.93%

explode()を使用して半角スペースを区切り文字として配列に分割して文字列を格納したいが分割ができない

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 12K+
退会済みユーザー

退会済みユーザー

失礼します。

explode()で半角スペースを区切り文字として入力された文字列を配列に格納しようと思っています。

入力された文字列:「り す」
配列:([0]り[1]す)

上のような状態に持って行きたいです。
伝わっているでしょうか?

explode()を使用している部分のコードはこちらです。

//三項演算子で検索文字列の有無を判定し処理
$data = isset($_POST['data']) ? trim($_POST['data']) : '';
//OR検索
$query = 'SELECT * FROM goods WHERE ';    //クエリ前半
$sql ="";
if($data){
    $count = 1;    //カウントを1にしておく
    $data = trim($data); //検索文字列の前後の空スペースだけを除去
    //全角スペースはmb_convert_kana()関数で半角スペースに変換
    $datalist = mb_convert_kana($data, 's');
    //print $datalist.'<br />';
    //複数キーワードでの検索
    //if(stristr($datalist," ")){
        //検索ワードをスペースで分割して配列に格納
        $keyword = explode(" ",$datalist);
コメントアウトの部分は確認用だったり必要か不要かが個人的に曖昧なものを残してあるだけなので無視してくださって構わないかと思います。

$keyword = explode(" ",$datalist);
ここの部分ですね。

現在の状態では、「り す」と入力すると配列の中身は([0]り す)となってしまいます。

どこが間違っているでしょうか?
よろしくお願いします。

念の為に全コードを載せておきます。

<?php
//  HTTPヘッダーで文字コードを指定
header("Content-Type:text/html; charset=UTF-8");
?>
<?php

//session_start();

//h()関数の読み込み
require_once 'lib/h.php';
//checkinput()関数の読み込み
require_once 'lib/checkinput.php';

//POSTされたデータのチェック
$_POST = checkinput($_POST);

//三項演算子で検索文字列の有無を判定し処理
$data = isset($_POST['data']) ? trim($_POST['data']) : '';
//OR検索
$query = 'SELECT * FROM goods WHERE ';    //クエリ前半
$sql ="";
if($data){
    $count = 1;    //カウントを1にしておく
    $data = trim($data); //検索文字列の前後の空スペースだけを除去
    //全角スペースはmb_convert_kana()関数で半角スペースに変換
    $datalist = mb_convert_kana($data, 's');
    //print $datalist.'<br />';
    //複数キーワードでの検索
    //if(stristr($datalist," ")){
        //検索ワードをスペースで分割して配列に格納
        $keyword = explode(" ",$datalist);
        //print_r ($keyword);
        //配列の数を数える
        $count = count($keyword);
        //空スペースで区切られた数によってSQL文を組み立てる
        for($i=0; $i<$count; $i++){//配列の数だけ繰り返す
            if($i!="0"){
                $sql = $sql." OR";
            }
        $sql = $sql." name LIKE :keyword ";
        }
    //}
}else{
    $count = 0;
}
//SQL文準備
$query = $query.$sql;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<meta http-equiv="content-script-type" content="text/javascript" />
<meta http-equiv="content-style-type" content="text/css" />
<!--  StyleSheet記述
<link rel="stylesheet" href="./css/main.css" type="text/css" media="all" />
StyleSheet記述  -->
<!-- PAGE TITLE -->
<title>ページタイトル</title>
</head>
<body>
<?php
if(!empty($datalist)){

    try{
        $username = "root";
        $password = "root";
        $pdo = new PDO(
            'mysql:host=localhost;dbname=shop',
            $username,
            $password,
            array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

        //プリペアドステートメントのエミュレーションを無効にする
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
        //エラーが発生した場合、例外がスローされるようにする
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

        //検索結果
        if($datalist <> ""){//検索窓が空なら検索しない
            //単ワードでの検索時
            if($count == 1){
                $datalist2 = '%'.$datalist.'%';    //検索文字列を%検索文字%とする
                $stmt = $pdo->prepare("SELECT * FROM goods WHERE name LIKE :datalist");
                $stmt->bindParam(':datalist',$datalist2,PDO::PARAM_STR);
                $stmt->execute(
                        );
                $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
                
            }//OR検索時
            elseif($count > 1){
                $stmt = $pdo->prepare($query);
                for($i=0; $i<$count; $i++){    //検索ワードの数だけ繰り返す
                    $keyword2[$i] = '%'.$keyword.'%';    //検索ワード1つ1つを%検索文字%にする
                    $holder = ':keyword'.$i;    //ホルダー用
                    $stmt->bindParam(':holder',$keyword2[$i],PDO::PARAM_STR);
                }
                $stmt->execute(
                        );
                $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
            }
        }


        if(count($result) == 0){
            print '<p>「'.h($data).'」はデータベースに登録がありません</p>';
        }else{
            print '<p>「'.h($data).'」はデータベースに登録がありました</p>';
?>
            <p>検索結果</p>
            <table>
            <tr>
                <th>商品名</th>
                <th>価格</th>
            </tr>
            
<?php

            foreach ($result as $row){
?>
            <tr>
                <td><?php print h($row['name']) ?></td>
                <td><?php print h($row['price']) ?></td>
            </tr>
<?php
            }
            print '</table>';
        }

//接続でいない場合、PDOException例外がスローされるのでキャッチする
    }catch(PDOException $e){
        print 'エラーが発生しました。。 内容:' . h($e->getMessage());
    }
}
?>
<p>検索したい文字列を入力</p>
<form action="list_s.php" method="POST" >
<input type="search" name ="data">
<input type="submit" value="検索">
</form>
</body>
</html>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+1

http://www.sitespiral.jp/archives/83.html

同じような壁にぶち当たり調べていたところ上記のサイトの対処で解決しました。
explode内の" "はbin2hex関数で「20」、切り出ししたい元の文字列には「20」がなく「C2A0」があったため分割が出来なかったようです。

str_replaceで置換した後、無事に分割できました。

------

str_replace( "\xc2\xa0", " ", $description );

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

$keyword = explode(" ",$datalist);

" "この部分の全角スペース/半角スペースを、もう一度確認してみてはどうでしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/08 19:21

    試しに全角スペースにしてみたらエラーになりました。

    キャンセル

0

動作を確認するために簡単なプログラムを組んでみたところ私の環境では動作しました。
<?php
mb_internal_encoding("UTF8");

function keywordSplit($data)
{
    $data = mb_convert_kana($data, 's');
    return explode(" ", $data);
}

// 半角スペース
var_dump(keywordSplit("り す"));
// 全角スペース
var_dump(keywordSplit("り す"));

/*
結果
array(2) {
  [0]=>
  string(3) "り"
  [1]=>
  string(3) "す"
}
array(2) {
  [0]=>
  string(3) "り"
  [1]=>
  string(3) "す"
}
*/
文字コードや、タイピングミスっぽい気がします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/08 19:37

    mysqlと連動しているのですが、mysqlの方でUTF8を指定すると文字化けをします。(なのでSJISで指定しています。)
    一方コード上ではUTF8を指定しています。
    原因はここでしょうか?

    キャンセル

  • 2015/01/08 19:45

    文字コードは統一しないと、色々と不具合が発生すると思います。
    mysqlがUTF8で指定すると文字化けするというのは、もしかしたらファイルをShiftJISなどで保存していないでしょうか?
    その辺りを再度確認したほうが良いかもしれません。

    キャンセル

  • 2015/01/08 20:41

    文字コードセットがUTF-8の状態になっていることを確認しファイルを保存して試しましたが変わりません。(SJISってShiftJISのことだったんですね…)
    文字コード関連だと、HTTPヘッダーでUTF8を指定しているのですが場所が悪いのでしょうか

    キャンセル

0

文字エンコーディングの整合性がとれていないので、$datalist = mb_convert_kana($data, 's'); が失敗しているのでしょう。

php.iniで文字エンコーディングをどう設定しているのか?
入ってくる文字エンコーディングは何か?
のあたりをチェックしてください。これが合ってないはずです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/13 11:47

    utf8と設定されています。

    キャンセル

  • 2015/01/13 22:05

    php.iniはutf8として、入ってくるデータの文字コードは何なのですか?それがutf8じゃないのでmb_convert_kanaが失敗しています。文字コードを合わせましょう。

    キャンセル

  • 2015/01/14 08:41

    入ってくるデータの文字コードはどこで確認できますか?
    mysql以外のどこを見てもUTF8で設定されています。

    キャンセル

0

この質問に関する新たな質問をするために、未だ解決していませんがここで一度回答をまとめさせていただきます。

まずphp.iniの文字エンコードの設定ですがutf8となっています。
$keyword = explode(" ",$datalist);
このコードについては半角になっています。
ちなみに全角スペースにして実行してみたところ、エラーになりました。

現在最も有力なものとして、mysqlの文字コードの問題が挙げられます。
utf8の設定ができないことが問題なのではないかと思っているので、次の質問で詳しく記述します。
回答をくださった皆様ありがとうございました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/13 22:02

    explodeはmysqlを呼び出す前の話なのでmysqlは関係ないです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • PHPに関する質問
  • explode()を使用して半角スペースを区切り文字として配列に分割して文字列を格納したいが分割ができない