1

私は自分のサイトの管理パネルに取り組んでおり、PHP とユーザーへのアクセスをより簡単に制御できるようにしています。プログラム内で SQL データベースに直接アクセスするコードを作成したくありませんが、他のユーザーがそれを使用するため、データベースに関する情報が漏洩したり、人々がアクセスしたりする危険を冒したくありません。そのため、ユーザー データベースのすべてのコンテンツを取得しようとしています。(「UserDB」と呼ばれるテーブル) をウェブサイトにエコーします。次のようなテーブル形式でこれを実行できることはわかっています: http://www.roseindia.net/sql/mysql-table/sqltable.shtmlしかし、私は思うこれは、すべての HTML を削除するためにさらに多くのコーディングを行うことを意味し、HtmlAgilityPack などの依存関係をインポートしたくありません。スプリッターを使用して各人の情報にアクセスできるように、テーブル全体を調べる方法はありますか?

IE は SQL テーブルのサイズをループして、次のような情報を取得します。

Garry:garrysemail@hotmail.com:registerd-Bob:bobs@gmail.com:guest

そして、C# を使用して「-」を分割して実際のユーザーを分離し、「:」を使用して情報を分離することができます。

これは、私が達成しようとしていることに関する私の C# プロジェクトのイメージです。これが私の質問に答えるのに十分な情報であることを願っています.

ここに画像の説明を入力

「テスト」/「テスト 2」は無視して、リスト ボックスにプレーンな文字列を追加できるかどうかを確認します。私は以前にそれらを使用したことがありません。

4

3 に答える 3

3

OK、実際に必要なのは、指定した形式 (< ユーザー名 >:< 電子メール >:< ユーザータイプ >-...) で SQL テーブルからデータを返す小さな PHP ページを作成することだけです。私はあなたがそれを行うことができると信じています:

function escape($str)
{
    $retn = str_replace("\\","\\\\",$str);
    $retn = str_replace("-","\\-",$retn);
    $retn = str_replace(":","\\:",$retn);
}
$result = SQL_QUERY_FUNCTION("SELECT * FROM UserDB");
$rowset = SQL_GET_ROWSET($result);
SQL_FREE_RESULT($result);
for ($i=0; $i<count($rowset); $i++)
{
    echo escape($rowset[$i]['username']);
    echo ":";
    echo escape($rowset[$i]['email']);
    echo ":";
    echo escape($rowset[$i]['usertype']);
    echo "-";
}

(SQLデータベースを取得する方法がわかりません。関数をほぼ同等のものに置き換えてください)

また、なぜエスケープ機能が必要なのかというと、サイトのセキュリティ上重要だからです。ただし、この場合は必ずしも必要ではありませんが、機能を拡張すると、穴が開いたままになる可能性があります。- が含まれるメールを想像してください: Garry:garry-email@hotmail.com:registered-... が Garry:garry and email になります@hotmail.com:分割時に登録!

次に、C# ループは次のようになります。

List<List<string>> users = new List<List<string>>();
List<string> user = new List<string>();
StringBuilder potato = new StringBuilder();
int i=0;
bool escaped=false;
while (i<userDB.Length)
{
    if (userDB[i] == '\\' && !escaped)
    {
        escaped = true;
    }
    else if (userDB[i] == ':' && !escaped)
    {
         user.Add(potato.ToString());
         potato.Clear();
    }
    else if (userDB[i] == '-' && !escaped)
    {
         user.Add(potato.ToString());
         potato.Clear();
         users.Add(user);
         user = new List<string>();
    }
    else
    {
        potato.Append(userDB[i]);
        escaped = false;
    }
}

必要に応じて、:s と -s を特別な Unicode 文字としてエンコードし、string.Split() 関数を使用して少し簡単にすることもできますが、この方法でも機能し、エンコーディングについて心配する必要はありません。

HTH。

編集: つまり、私たちが行っているのは、文字列を再度読み取れるようにパックすることです。ここでの最大の問題は、文字列をエスケープすることです。他の誰かが言及したように、JSON は実際にここで進むべき道かもしれません (それを忘れてしまった...)。それにもかかわらず、私は自分の答えをさらに説明するためにここにいます。つまり、: と - をトークンとして使用して、それらを使用してデータを読み取り可能なブロックに分離するという考え方です。これを使用して 4 つの hello をエンコードすると、次のようになります。

Hello:Hello:Hello:Hello

これらの4行をエンコードしたいとしましょう

He:llo
Hell:o
Hello
Hello

したがって、エスケープを無視すると、次のようになります

He:llo:Hell:o:Hello:Hello

プログラムがこれらを分離しようとすると、次のようになります。

He
llo
Hell
o
Hello
Hello

これは確かに、以前に入れたことではありません。そのため、エスケープを使用します。文字列の中に " を入れる場合、その前に \ を置かなければならないことはおそらくご存じでしょう。なぜでしょうか? 同じ理由: コンピューターが、途中の " と末尾の " を区別する方法がありません。文字列. したがって、引用符を「エスケープ」します. コンピュータが \ を検出するたびに、\ と次の文字を結合すると想像してください. したがって、2 つの引用符を簡単に区別できるようになりました:

"Hello, My name is "Matt""

"Hello, My name is \"Matt\""

見る?\ がそれ自体と次の文字を結合することを理解した上で、スラッシュを 1 つ入れる唯一の方法は、2 つ入れることです。

Console.WriteLine("This is a slash in quotes: \"\\\"");

出力します:

This is a slash in quotes "\"

したがって、エスケープについて今知っていることを使用して、それをプログラムできます。最初に行うことは、すべてのエスケープ文字 ( ) をエスケープすることです。(最初にこのステップを実行する必要があります。後で説明します)

$retn = str_replace("\\","\\\\",$str);

文字列 $str 内のすべての \ を \ に置き換え、$retn に入れます。ただし、覚えておいてください: \ は PHP のエスケープ文字でもあります! そのため、php に何を置き換えるかを伝えるには、それもエスケープする必要があります。とても紛らわしいですね。

次に、文字列内のトークンをエスケープします。このようにして、-s と :s が誤ってトークンとして認識されることはありません。-s を - に、:s を \: に置き換えるだけです。簡単です。

$retn = str_replace("-","\\-",$retn);
$retn = str_replace(":","\\:",$retn);

難しいのは読むことです: 読むためには、一度に 1 文字ずつ文字列を最後までたどらなければなりません。つまり、「\」を読み取るたびに、次の文字が持つ可能性のある特別な意味を無視します。それ以外の場合は、リストを分割します。見てみましょう:

List<List<string>> users = new List<List<string>>();

リストのリスト: ユーザー名、電子メール、およびユーザータイプの 3 つの文字列のコレクションのグループ。

List<string> user = new List<string>();

これは、データを追加している現在のユーザーです。- に到達するまで、読み取った各文字列をこのリストに追加します。その場合、ユーザーをユーザーに追加し、次のデータ ロット用に新しいユーザーを作成します。

StringBuilder potato = new StringBuilder();

ここで StringBuilders を使用する理由については説明しませんが、基本的には、StringBuilders によってプログラムの速度が大幅に向上するということです。

string bob = "";
bob += "a";
bob += "b";
bob += "c";

したがって、メインループに到達します。

while (i<userDB.Length)
{

ダウンロードした文字列の各文字について...

if (userDB[i] == '\\' && !escaped)
{
    escaped = true;
}

それがスラッシュであり、スラッシュが前になかった場合、次の文字にその前にスラッシュがあったことを伝えます。

else if (userDB[i] == ':' && !escaped)
{
     user.Add(potato.ToString());
     potato.Clear();
}

コロンであり、スラッシュが前に付いていない場合は、ロードされた文字列の現在の内容をユーザーに入力し、それをクリアしてデータを追加します。

else if (userDB[i] == '-' && !escaped)
{
     user.Add(potato.ToString());
     potato.Clear();
     users.Add(user);
     user = new List<string>();
}

それが - であり、スラッシュがその前にない場合、ロードされた文字列の現在の内容をユーザーに入れ、それをクリアして追加のデータを取得し、かつユーザーをユーザーのリストに追加し、次のデータのロットのために別のユーザーを作成します.

else
{
    potato.Append(userDB[i]);
    escaped = false;
}

文字がエスケープされているか、/、:、または - でない場合は、現在読み込まれている文字列に追加し、エスケープ フラグをクリアします (つまり、次の文字にスラッシュが前にないことを伝えます。

問題が解決することを願っています。前述したように、とにかく JSON がこれらすべてを行います。しかし、下にあるものを理解していなければ、自分でそれを行う方法を学ぶことはできません!

編集 2

コンピュータに文字列を格納するには、主に 2 つの方法があります。最初の方法は、単語の長さを書き、次に単語を書きます。

5 Hello

2 番目の方法は、文字列がメモリに格納され、null(0) で終了する場所です。文字は、エンコーディング (UTF8、UTF16/Unicode、UTF32) に応じて、1、2、または 4 バイトの Unicode で表されることを理解しています。実際、文字「A」は数字の 65 として格納されます。B は数字の 66 などです。ポイントは、ターミネータ文字である番号 0 を選択することです。実際、「ABC」は次のように格納されます (10 進数):

65 66 67 0

しかし、文字列を英語で書いていなかったらどうでしょう。その文字列の途中に 0 を入れる必要がある場合はどうなるでしょうか。

1 2 3 4 0 1 2 3 4 0

コンピュータが文字列を読み取るとき、最後ではなく真ん中の 0 で終わると考えます。今から何をする?ほとんどの場合、オプション 1 を選択します。長さを送信してから、文字列自体を送信します。これを行うこともできますが、ここでは説明しない理由により、うまく機能しません。

では、中間の 0 と最後の null 0 を区別するにはどうすればよいでしょうか? この文字列を終了するために 5 と言うことができます。文字列にも 5 を追加する必要があるまで、何も問題はありません。だから私たちは賢いことをします。エスケープ文字を選択します。文字列読み取りループからエスケープし、次の文字を命令として使用します。基本的な考え方は次のとおりです。

この文字はエスケープ文字ですか? YES: 次のキャラクターをつかみます。次の文字が "A" の場合: 文字列にエスケープ文字を入れます (エスケープ文字をエンコードする方法があります) 次の文字が "!" の場合: 文字列は終了です! それ以外の場合: エラー。いいえ: 次の文字に移動します。

このタイプのコードでは、エスケープ文字 B を選択するとします。文字列 "ABCDEFG" をエンコードしてみましょう。

まず、コンピュータが B に到達し、「C」を命令として使用しようとしてエラーになることがわかります。したがって、B をエンコードするには、その後に A を貼り付けます。通常、エスケープ文字をエンコードするための命令文字をエスケープ文字そのものとして選択します。その方が見栄えがよく、特別な理由はありません。次に行う必要があるのは、「B!」を追加して文字列が終了したことをコンピューターに伝えることです。最後まで。したがって、最終的な文字列は次のようになります。

ABACDEFGB!

では、これはあなたの問題にどのように当てはまりますか? コロンで区切りたい電子メール アドレスとユーザー名があります。ユーザー名自体にコロンが含まれている場合、プログラムは名前の末尾に到達したと見なします。

Bob:Boberty:Bob@bob.com:registered

コンピュータは、「Boberty」が電子メールであると自動的に想定します。名前のコロンと、文字列を終了するコロンを区別する方法を指定する必要があります。逃げることが答えです。

于 2013-01-05T03:07:01.343 に答える
1

人々がしていることは非常に複雑に思えます。あなたができることは、配列リストでループを使用することです。ただし、最初にMySQLテーブルのテーブルサイズを取得して配列に入力を追加し、そのサイズをループして、「-」で区切られたすべての入力を追加します。次に、それらをループして、arraylist で分離します。何かのようなもの

for(int x = 0;x < ArrayList.Size();x++)
{
      String[] Details = x.Split(new char[] { '-' });
      Lists.items.add(Details[0].trim());
}

詳細を正しく取得すれば、正常に動作するはずです。私は1回の入力で簡単にそれをしませんでした。

于 2013-01-11T14:09:43.000 に答える
1

をご覧になることをお勧めします JSON。マルチ配列をJSONwithjson_encode($array)に変換でき、c#JavaScriptSerializerではそれを配列にデコードするために使用できます。

于 2013-01-05T02:51:54.807 に答える