スレッド表示 | フラット表示〕 全トピック 920 件中 710 番目 次≫ ≪前

一部文字列にて検索時にエラー

created: 2003-12-13 19:01 | modified: 2003-12-28 14:20 | reply: 12

[1152] 一部文字列にて検索時にエラー

user: べんじゃみん ホームページ | created: 2003-12-13 19:01
現在、サンプルソースを元に検索結果をテーブルで表示させようと
思っているのですが、一部文字列で以下のようにエラーを返します。

この行でエラーを返します。

117 $num_rows = mysql_num_rows($result);

141 <?php mysql_free_result($result);?>

エラーを返す文字列は、「能」「ー」「?」「タ」です。
その他は、今のところ問題ないようなのですが・・・。

ささやかな情報でも結構ですので、何かお気付きの方がいらっしゃい
ましたら、ご教授頂けますでしょうか。

よろしくお願い致します。

全ソースは以下のようになっております。

<?php require_once('connections.php'); ?>
<?php
$colname_Record = "1";
if (isset($HTTP_GET_VARS['oldcode'])) {
$colname_Record = (get_magic_quotes_gpc()) ? $HTTP_GET_VARS['oldcode'] : addslashes($HTTP_GET_VARS['oldcode']);
}
mysql_select_db($database_test, $test);
$query_Record = sprintf("SELECT * FROM jirei1 WHERE oldcode = '%s'", $colname_Record);
$Record = mysql_query($query_Record, $test) or die(mysql_error());
$row_Record = mysql_fetch_assoc($Record);
$totalRows_Record = mysql_num_rows($Record);
?>
<body bgcolor=white background="blue2.png">
<?php
include "pref.php"; /* 担当者データを取り込む */
include "config.inc.php"; /* DB情報を取り込む */
$link = mysql_connect("$host","$dbuser", "$pass") or die(mysql_error());
mysql_select_db("$dbname", $link) or die(mysql_error()); ?>
<?php print("<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>\n");
print("<html>\n");
print("<head>\n");
print("<title>searching result of jirei oldcode</title>\n");
print("<meta http-equiv=content-type content='text/html; charset=Shift-jis'>\n");

print("</head>\n");
print("<body bgcolor=white>\n");

/* シート番号フィールドの問い合わせ作成。数字以外の文字は無視する */
function makeup1($name,$value) {
global $f,$query;
if ($value != "") {
$value = mysql_escape_string(ereg_replace("[^0-9]","",$value));
if ($f) {
$query = $query . " and";
} else {
$query = $query . " where";
}
$query = $query . " $name = '$value'";
$f++;
}
};?>
<?php /* 担当者コードフィールドの問い合わせ作成 */
function makeup2 ($name,$value) {
global $f,$query;
if ($value != -1) {
if ($f) {
$query = $query . " and";
} else {
$query = $query . " where";
}
$query = $query . " $name = '$value'";
$f++;
}
};?>
<?php /* 品名・単価・個数などの文字列フィールドの問い合わせ作成。
* 無条件に前方一致検索を行う
*/
function makeup3 ($name,$value) {
global $f,$query;
if ($value != ".*") {
$value = strip_tags($value);
if (substr($value,0,1) != ".") {
$value = ".*" . $value;
}

if ($f) {
$query = $query . " and";
} else {
$query = $query . " where";
}
$query = $query . " $name regexp '$value'";
$f++;
}
};

/* 問い合わせ文字列格納用の変数 */
$query = "select naiyou,oldcode,pid,daimei,ranpu,syoujyou,genin from jirei1 ";

/* 検索条件があるかどうかのフラグ */
$f = 0;

makeup1("oldcode",$_POST['oldcode']); /* シート番号 */
makeup1("newcode",$_POST['newcode']); /* */
makeup2("pid",$_POST['prefecture']); /* 担当者コード */
makeup3("naiyou",$_POST['daimei']); /* 品名 */
makeup3("ranpu",$_POST['ranpu']); /* 単価 */
makeup3("syoujyou",$_POST['syoujyou']); /* 個数 */
makeup3("genin",$_POST['genin']); /* 備考 */

if ($f) {
$query = $query . " order by oldcode";
} else {
print("検索キーが設定されていません。\n");
exit;
}


/* デバッグオプションがオンならSQL文を表示する */
if ($_POST['sqlprint']) {
print("以下のSQL文を発行しました。<br>$query<br><br>\n");
}

print("<h1>検索結果</h1>ブラウザの「戻る」ボタンにて前画面に戻ってください。");
?>
<table border bgcolor="#FFFFFF">
<tr>
<th nowrap bgcolor="#CCCCCC">シート</th>
<th nowrap bgcolor="#CCCCCC">担当者</th>
<th nowrap bgcolor="#CCCCCC">品名</th>
<th nowrap bgcolor="#CCCCCC">単価</th>
<th nowrap bgcolor="#CCCCCC">個数</th>
<th nowrap bgcolor="#CCCCCC">備考</th>
</tr>
<?php

$result = mysql_query($query, $link); /* */
$num_rows = mysql_num_rows($result); /* */

if ($_POST['ulimit'] < $num_rows) {
$cnt = $_POST['ulimit'];

}
else {
$cnt = $num_rows;
echo "$num_rows 件見つかりました。<br>\n";
}

/* テーブル形式でデータを表示 */
for($i=0;$i < $cnt;$i++) {
print("<td nowrap><a href=detail.php?Record=" . mysql_result($result,$i,1) . " target=\"mainFrame\" > " . mysql_result($result,$i,1) . " </td>\n");

print("<td nowrap>" . $pref_tbl[mysql_result($result,$i,2)] . "</a></td>\n");
print("<td nowrap>" . mysql_result($result,$i,3) . "</td>\n");
print("<td nowrap>" . mysql_result($result,$i,4) . "</td>\n");
print("<td nowrap>" . mysql_result($result,$i,5) . "</td>\n");
print("<td nowrap>" . mysql_result($result,$i,6) . "</td>\n");
print("</tr>\n");
}
?>

<?php mysql_free_result($result);?>

</table>
</body>
</html>
<?php
mysql_free_result($Record);
?>
reply: 1153 返信 編集 削除

[1153] エラーメッセージは?

user: ゆうじ | created: 2003-12-13 19:30
挙げていただいたコードはまだ見れてませんが、
先ず、気になるエラーメッセージは、
どのようなものでしたか?
Parent: 1152  reply: 1154 返信 編集 削除

[1154] 以下の通りです。

user: べんじゃみん ホームページ | created: 2003-12-13 20:49
ある文字列で検索を実行すると、以下のようなエラーを返します。

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in ******* on line 117

Warning: mysql_free_result(): supplied argument is not a valid MySQL result resource in ******* on line 141

ある特定文字列だけなので、素人ながらにクエリーが怪しいのかなとも思っているのですが。

もし、情報が不足しているようでしたら、再度ご報告させて頂きますので、どうぞよろしくお願い致します。
Parent: 1153  reply: 1155 返信 編集 削除

[1155] magic_quotes_gpc の影響かな

user: ゆうじ | created: 2003-12-13 23:02
> ある特定文字列だけなので、素人ながらにクエリーが怪しいのかなとも思っているのですが。

エラーメッセージからするとそのようです。
クエリがSQL文としておかしいので、
116 | $result = mysql_query($query, $link); /* */
の戻り値がMySQLのリソースではない(おそらくfalse)、
よって117行目以降でエラーとなってるのでしょう。

怪しいのはこの関数。
function makeup3 ($name,$value) {
global $f,$query;
if ($value != ".*") {
$value = strip_tags($value);
if (substr($value,0,1) != ".") {
$value = ".*" . $value;
}
・・・以下省略・・・

こちらの $value は、$_POST の値が渡されるようですが、
magic_quotes_gpcに対する処理がありません。

magic_quotes_gpc = On、さらにShift-JISで「能(\x945C)」が与えられた場合、
「能」の2バイト目が「\(0x5C)」と判断され、
「能\(\x945C + \x5C)」という文字がスクリプトに渡されます。

「\」はMySQLでもエスケープ文字として扱われますので、
このままSQLに投げた場合、「\」の次の文字の1バイト目が、
エスケープの対象になってるのではないでしょうか。

if(get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
これを、makeup3関数のはじめに挿入してみてはいかがでしょうね。
Parent: 1154  reply: 1156 返信 編集 削除

[1156] やはりエラーが・・・

user: べんじゃみん ホームページ | created: 2003-12-14 09:22
初心者ということもあり、PHPマニュアルと引き合わせながら、確認しています。
以下のようにしましたが、やはり同様のエラーがでてしまいます。

function makeup3 ($name,$value) {
global $f,$query;
if(get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
if ($value != ".*") {
$value = strip_tags($value);
if (substr($value,0,1) != ".") {
$value = ".*" . $value;
}

if ($f) {
$query = $query . " and";
} else {
$query = $query . " where";
}
$query = $query . " $name regexp '$value'";
$f++;
}
};

もし、挿入の方法が間違っているようでしたら、ご指摘頂ければ幸いです。
よろしくお願い致します。
Parent: 1155  reply: 1159 返信 編集 削除

[1159] 基本に返って

user: ゆうじ | created: 2003-12-14 16:01
挿入の方法は間違ってないです。
変らないのであれば違うところが原因のようですね。

基本に返って、
117行目実行前に、$query を確かめて見る必要がありますね。
var_dump($query);
これで思い通りのクエリーになっていれば良いのですが。


別の提案ですが、ソース5行目。
$colname_Record = (get_magic_quotes_gpc()) ? $HTTP_GET_VARS['oldcode'] : addslashes($HTTP_GET_VARS['oldcode']);
magic_quotes_gpc が Off ならば、エスケープする仕様になってますね。
同じように問い合わせ前に、エスケープする必要があるのかもしれません。
Parent: 1156  reply: 1160 返信 編集 削除

[1160] 試してみました。

user: べんじゃみん ホームページ | created: 2003-12-14 20:16
var_dump($query);
にて確認致しましたところ、
string(188) "select naiyou,oldcode,pid,daimei,ranpu,syoujyou,genin from jirei1 where naiyou regexp '.*' and ranpu regexp '.*' and syoujyou regexp '.*' and genin regexp '.*能\' order by oldcode"
string(185) "select naiyou,oldcode,pid,daimei,ranpu,syoujyou,genin from jirei1 where naiyou regexp '.*' and ranpu regexp '.*' and syoujyou regexp '.*' and genin regexp '.*質' order by oldcode" 3 件見つかりました。
となりました。
キーワードで検索すると、
string(179) "select naiyou,oldcode,pid,daimei,ranpu,syoujyou,genin from jirei1 where naiyou regexp '.*質' and ranpu regexp '.*' and syoujyou regexp '.*' and genin regexp '.*' order by oldcode" 6 件見つかりました。
string(180) "select naiyou,oldcode,pid,daimei,ranpu,syoujyou,genin from jirei1 where naiyou regexp '.*能\' and ranpu regexp '.*' and syoujyou regexp '.*' and genin regexp '.*' order by oldcode"
となりました。
他の検索できない文字である"タ”などで試すと、
string(179) "select naiyou,oldcode,pid,daimei,ranpu,syoujyou,genin from jirei1 where naiyou regexp '.*タ' and ranpu regexp '.*' and syoujyou regexp '.*' and genin regexp '.*' order by oldcode" 0 件見つかりました。
となることから、素人ながらに"\"はあまり関係がないような気も致します。

すみません。
$colname_Record = (get_magic_quotes_gpc()) ? $HTTP_GET_VARS['oldcode'] : addslashes($HTTP_GET_VARS['oldcode']);
については、具体的にどのように対処すべきかが分かりませんでした。
勉強不足で申し訳ございません。
Parent: 1159  reply: 1163 返信 編集 削除

[1163] 正規表現の特殊文字

user: ゆうじ | created: 2003-12-14 22:03
原因がわかりました。
正規表現の特殊文字がこのエラーの原因のようです。

問題のある文字のコードをよくよく確かめたら気づきました。
以下の文字の2バイト目は、正規表現の特殊文字と一致します。
このため、これらの文字がregexpで正規表現の特殊文字と判断され、
エラーになっていたのだと思われます。

 文字 | SJIS   | 2バイト目
------+--------+-----------
タ | 835E | ^
------+--------+-----------
能 | 945C | \
------+--------+-----------
ー | 815B | [
------+--------+-----------
? | 817C | |

対策をGoogleで探してみましたが、
regexpはマルチバイト未対応という、
悲しい物しか見つけることが出来ませんでした。
文字コードがSJISではこの現象を避けることは出来ないのだろうと思います。

regexp ではなく like を使用するというのが、
もっとも簡単な対応策のようです。
Parent: 1160  reply: 1170 返信 編集 削除

[1170] なるほど!

user: べんじゃみん ホームページ | created: 2003-12-15 15:32
正規表現の問題だったんですね。

likeを使った部分検索を調べていたのですが、
いまいち理解できませんでした。
"name like '%" . $name . "%'"
みたいな感じになるようなのですが・・・。

他力本願で申し訳ございませんが、

function makeup3 ($name,$value) {
global $f,$query;
if ($value != ".*") {
$value = strip_tags($value);
if (substr($value,0,1) != ".") {
$value = ".*" . $value;
}

if ($f) {
$query = $query . " and";
} else {
$query = $query . " where";
}
$query = $query . " $name regexp '$value'";
$f++;
}
};

部分をlikeを使った部分一致検索へ書き換える方法をご教授頂ければ幸いです。
Parent: 1163  reply: 1172 返信 編集 削除

[1172] 実行

user: ゆうじ | created: 2003-12-15 16:58
> likeを使った部分検索を調べていたのですが、
> いまいち理解できませんでした。
> "name like '%" . $name . "%'"
> みたいな感じになるようなのですが・・・。

私もそうなると思います。
もう私からお伝えできることは無い様に思います。
思うことは、先ず確かめてみましょう。
ご質問があればその後で。
Parent: 1170  reply: 1183 返信 編集 削除

[1183] その後・・・

user: べんじゃみん ホームページ | created: 2003-12-23 15:06
ご返信が送れてすみませんでした。

likeを使って、以下のように修正しましたところ、「ー」「?」「タ」は検索可能となりましたが、何故か「能」だけ検索するとエラーは返しませんが、"0件見つかりました"という表示しか返しませんでした。

正規表現以外に何か問題があるのでしょうか。
もし、何かお気付きの点がありましたら、ご教授頂きますよう、よろしくお願い致します。

function makeup3 ($name,$value) {
global $f,$query;
if ($value != -1) {
if ($f) {
$query = $query . " and";
} else {
$query = $query . " where";
}
$query = $query . " $name like '%$value%'";
$f++;
}
};
Parent: 1172  reply: 1184 返信 編集 削除

[1184] mysql_escape_string

user: ゆうじ | created: 2003-12-23 18:24
$value が「能」の場合は、'%能%' となるのだと思いますが、
能の2バイト目が 0x5C (\)なので、
\ が MySQLのエスケープ文字だと解釈されてるのではないでしょうか。
こんなイメージ。
% + 0x94 + \ + %

mysql_escape_string関数 で
あらかじめ、$value をエスケープしておくと
良いのではないでしょうか。
Parent: 1183  reply: 1188 返信 編集 削除

[1188] 解決しました!

user: べんじゃみん ホームページ | created: 2003-12-28 14:20
またまた返信が遅れてしまい、申し訳ございませんでした。
mysql_escape_string関数を使ってみましたが、状況は変わりませんでした。

そこで、いろいろ調べてみたところ、以下のような構文を挿入して問題解決致しました。

$value = stripslashes($value);

いろいろとご迷惑をお掛け致しました。
今後ともよろしくお願い致します。
Parent: 1184  返信 編集 削除
スレッド表示 | フラット表示〕 全トピック 920 件中 710 番目 次≫ ≪前
ページの一番上へ
Googleグックマークに登録 Yahooグックマークに登録 livedoorクリップに登録 @niftyクリップに登録 はてなブックマークに登録 deliciousに登録 Buzzurlに登録 FC2ブックマークに登録
最近更新された掲示板トピックス
管理人Blog
Yahoo Search

最近更新したNote
PHPマニュアル
今日のブックマーク
PHPマニュアル関数検索
関数名を入力し検索ボタンをクリック↑