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

好的,看来您只需要创建一个小的 PHP 页面,该页面以您指定的格式(< username >:< email >:< usertype >-...)从 SQL 表中返回数据。我相信您可以做到这一点,只需执行以下操作:

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 和电子邮件@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

这肯定不是我们之前放入的。所以我们使用转义。您可能知道,如果您在字符串中添加 ",则必须在其前面添加 \。为什么?同样的原因:计算机无法区分中间的 " 和结尾的 "字符串。所以我们“转义”了引号。想象每次计算机看到一个 \,它连接 \ 和下一个字符。所以现在很容易区分两个引号:

"Hello, My name is "Matt""

对比

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

看?现在了解 \ 连接自身和下一个字符,放入一个斜线的唯一方法是放入两个:

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

会输出:

This is a slash in quotes "\"

因此,根据我们现在对转义的了解,我们可以对其进行编程。我们要做的第一件事是转义所有转义字符(即 a )。(我们要先做这一步,后面我会解释)

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

它将字符串 $str 中的每个 \ 替换为 \ 并将其放入 $retn 中。但请记住:\ 也是 PHP 的转义字符!因此,要告诉 php 替换什么,我们也必须将其转义!很纠结哈。

接下来,我们对字符串中的标记进行转义:这样 -s 和 :s 就不会被意外地视为标记。我们只需将 -s 替换为 - 并将 :s 替换为 \:,很简单:

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

更难的是阅读:要阅读,我们必须一次一个字符地遍历字符串,直到到达结尾。所以:每次我们读到一个“\”,我们都会忽略下一个字符可能有的任何特殊含义。否则,我们拆分列表。让我们来看看:

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

列表列表:一组 3 个字符串、用户名、电子邮件和用户类型的集合。

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

这是我们正在向其添加数据的当前用户。我们将读取的每个字符串添加到此列表中,直到到达 -。当我们这样做时,我们只是将用户添加到用户,并为下一批数据创建一个新用户。

StringBuilder potato = new StringBuilder();

我不会在这里讨论为什么我们应该使用 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

在计算机中存储字符串有两种主要方法。第一种方法是我们写单词的长度,然后我们写单词。

5 Hello

第二种方式是将字符串存储在内存中并以 null(0) 结尾。您了解字母由它们的 Unicode 表示,根据编码(UTF8、UTF16/Unicode、UTF32)以 1、2 或 4 个字节表示。事实上,字母“A”存储为数字 65。B 是数字 66,依此类推。关键是我们选择了一个终止符,数字 0。所以实际上“ABC”是这样存储的(十进制):

65 66 67 0

但是如果我们不是用英文写一个字符串怎么办。如果我们需要在该字符串的中间放置一个 0 怎么办:

1 2 3 4 0 1 2 3 4 0

当计算机读取字符串时,它认为它在中间的 0 处结束,而不是在结尾处。那么,我们现在该怎么办?在大多数情况下,我们选择选项 1。我们传输长度,然后传输字符串本身。你可以这样做,但由于我不会讨论的原因,它不会很好地工作。

那么我们如何区分中间的 0 和最终的 null 0 呢?我们可以选择 5 来结束这个字符串,除非我们也需要在字符串中放入 5,否则不会出错。所以我们做了一些聪明的事情。我们选择一个转义字符:它从字符串读取循环中转义并使用下一个字符作为指令。这是基本思想:

这个字符是转义字符吗?是:抓住下一个字符。如果下一个字符是“A”:在字符串中放一个转义字符(所以有一种编码转义字符的方法)如果下一个字符是“!”:字符串完成!否则:错误。否:转到下一个字符。

所以对于这种类型的代码,假设我们选择了转义字符 B。让我们尝试对字符串“ABCDEFG”进行编码。

首先,我们可以看到计算机将到达 B 并尝试使用“C”作为指令并遇到错误。所以为了对 B 进行编码,我们在它后面加上一个 A。通常,我们选择将转义字符编码的指令字符作为转义字符本身:这样看起来更整洁,没有特殊原因。接下来我们需要做的是通过添加“B!”告诉计算机字符串已完成。到最后。所以我们的最终字符串如下所示:

ABACDEFGB!

那么这如何适用于您的问题?您有希望用冒号分隔的电子邮件地址和用户名。如果用户名本身包含冒号,程序将假定已到达名称的末尾。

Bob:Boberty:Bob@bob.com:registered

计算机将自动假定“Boberty”实际上是电子邮件。您需要告诉它如何区分名称中的冒号和结束字符串的冒号。逃避就是答案。

于 2013-01-05T03:07:01.343 回答
1

我建议你看看 JSON。您可以将多数组转换为JSONwithjson_encode($array)并且在 c# 中您可以使用JavaScriptSerializer它来将其解码为数组。

于 2013-01-05T02:51:54.807 回答
1

人们在做什么似乎很复杂。您可以做的是使用带有数组列表的循环。但首先通过获取 MySQL 表的表大小将输入添加到数组中,循环通过该大小并添加由“-”分隔的所有输入。然后循环它们并将它们分开在arraylist中。就像是

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

如果您正确获取详细信息,应该可以正常工作。我没有简单地输入一个输入。

于 2013-01-11T14:09:43.000 回答