这里的想法是创建一个 PHP 结构,该结构具有 JSON 中存在的数据,然后使用 json_encode() 将该结构转换为 JSON。
如果您查看class User,它代表一个用户和所有后代。
如果我可以用所有数据填充它,那么将其转换为 JSON 很容易。
请注意,表中的每个用户都有一个父级,该父级存储在列referredby_id 中。这是父用户的主键。
只要保证表中的用户名是唯一的,您就可以将其更改为用户名。
为此,请将referredby_id 列的类型更改为VARCHAR。如果数据量大,则索引用户名表。
表:
CREATE TABLE `affilitateuser` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(40) DEFAULT NULL,
`referredby_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
数据:
INSERT INTO `affilitateuser` (`id`, `username`, `referredby_id`) VALUES
(1, 'sarah', NULL),
(2, 'james', 1),
(3, 'tom', 2),
(4, 'natalie', 3),
(5, 'juan', NULL),
(6, 'jose', 5),
(7, 'alberto', 5),
(8, 'fernando', 5),
(9, 'camila', 8),
(10, 'sean', 9),
(11, 'scotty', 9),
(12, 'robert', 9),
(13, 'montgomery', 12),
(14, 'jessie', 13),
(15, 'cole', 13),
(16, 'cary', 14),
(17, 'porter', 14),
(18, 'sandra', 5),
(19, 'lily', 6);
代码:
// A class to represent nodes on a tree
class User
{
public $name;
public $children = [];
public function __construct($name)
{
$this->name = $name;
}
// Add a child to this User
public function addChild($name)
{
$u = new User($name);
$this->children[] = $u;
// return the newly created object so we can use it later.
return $u;
}
}
// Class that does the extracting
class UserTreeExtractor
{
protected $conn; // keep the database connection
public function run()
{
$this->connect();
// Extract Juan's tree
// print_r($this->tree(5));
// Save the JSON to a string
$jsonString = json_encode($this->tree(5), JSON_PRETTY_PRINT);
// Write it out to a file
file_put_contents('output.json', $jsonString);
}
// { "name": "juan ", "children": [ { "name ": "jose", "children": [{ "name": "fernando", "children": [] }] } { "name": "alberto", "children": [] } ] },
/**
* Gets the children and downstream descendants for a user
*/
protected function tree($id)
{
// First, get the user
$sql1 = "SELECT username FROM affilitateuser WHERE id = {$id}";
$stmt = $this->conn->prepare($sql1);
if ( ! $stmt ) {
die('query failed');
}
$stmt->execute();
$top = $stmt->get_result()->fetch_assoc();
// print_r($top); exit();
// Now get the all descendents
$sql = "SELECT id, username, referredby_id
FROM (SELECT * FROM affilitateuser
ORDER BY referredby_id, id) users_sorted,
(SELECT @pv := '{$id}') initialisation
WHERE find_in_set(referredby_id, @pv)
AND LENGTH(@pv := CONCAT(@pv, ',', id))";
// "SELECT username FROM `affiliateuser` WHERE referedby_id = {$id}"
$stmt = $this->conn->prepare($sql);
$stmt->execute();
$children = [];
$tree = new User($top['username']);
// Keep an index of where the objects are stored
// so we can find them later to attach their children.
$index[$id] = $tree;
$parent = null;
foreach ($stmt->get_result() as $row)
{
if ( isset($index[$row['referredby_id']]) ) {
$new = $index[$row['referredby_id']]->addChild($row['username']);
$index[$row['id']] = $new; // put the new user into the index
} else {
// referred by some user that does not exist
die("Referred by non-existent user");
}
$children[] = ['username' => $row['username'], 'id' => $row['id'], 'referredby_id' => $row['referredby_id']];
}
return $tree;
}
// Connect to the database
protected function connect()
{
// Change the connection credentials as needed.
$this->conn = mysqli_connect("127.0.0.1", "app", "aaaa", "sss");
if( ! $this->conn ) {
die("Database Connection Failed: ".mysql_error());
}
}
}
$obj = new UserTreeExtractor;
$obj->run();