Автор оригинала: David Wong.
В этой статье описывается, как PHP использует многопоточность pthreads V3 для сбора информации о новостях Sina. Подробности заключаются в следующем:
Мы используем pthreads для написания многопоточного апплета захвата страниц и сохранения результатов в базе данных.
Структура таблицы данных выглядит следующим образом:
CREATE TABLE `tb_sina` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`URL ` varchar (256) default '' comment 'URL address',
`Title ` varchar (128) default '' comment 'title',
`time` datetime DEFAULT NULL ON UPDATE CURRENT_ Timestamp comment 'time',
PRIMARY KEY (`id`)
)Engine = InnoDB default chart = utf8mb4 comment ='sina news';
Код выглядит следующим образом:
php
class DB extends Worker
{
private static $db;
private $dsn;
private $root;
private $pwd;
public function __construct($dsn, $root, $pwd)
{
$this->dsn = $dsn;
$this->root = $root;
$this->pwd = $pwd;
}
public function run()
{
//Create connection object
self::$db = new PDO($this->dsn, $this->root, $this->pwd);
//Put require in the worker thread, not in the main thread, otherwise an error will be reported and no class will be found
require './vendor/autoload.php';
}
//Returns a connection resource
public function getConn()
{
return self::$db;
}
}
class Sina extends Thread
{
private $name;
private $url;
public function __construct($name, $url)
{
$this->name = $name;
$this->url = $url;
}
public function run()
{
$db = $this->worker->getConn();
if (empty($db) || empty($this->url)) {
return false;
}
$content = file_get_contents($this->url);
if (!empty($content)) {
//Get title, address, time
$data = QL\QueryList::Query($content, [
'tit' => ['.c_tit > a', 'text'],
'url' => ['.c_tit > a', 'href'],
'time' => ['.c_time', 'text'],
], '', 'UTF-8', 'GB2312')->getData();
//Insert the acquired data into the database
if (!empty($data)) {
$sql = 'INSERT INTO tb_sina(`url`, `title`, `time`) VALUES';
foreach ($data as $row) {
//Modify the time. Sina's time format is 04-23 15:30
$time = date('Y') . '-' . $row['time'] . ':00';
$sql .= "('{$row['url']}', '{$row['tit']}', '{$time}'),";
}
$sql = rtrim($sql, ',');
$ret = $db->exec($sql);
if ($ret !== false) {
Echo "thread {$this - > name} successfully inserted {$RET} pieces of data;
} else {
var_dump($db->errorInfo());
}
}
}
}
}
//Grab page address
$url = 'http://roll.news.sina.com.cn/s/channel.php?ch=01#col=89&spec=&type=&ch=01&k=&offset_page=0&offset_num=0&num=60&asc=&page=';
//Create pool
$pool = new Pool(5, 'DB', ['mysql:dbname=test;host=192.168.33.226', 'root', '']);
//Get 100 paging data
for ($ix = 1; $ix <= 100; $ix++) {
$pool->submit(new Sina($ix, $url . $ix));
}
//Loop garbage collection, blocking the main thread, waiting for the end of the child thread
while ($pool->collect()) ;
$pool->shutdown();
Благодаря использованию списка запросов вы можете установить его через composer.
composer require jaeger/querylist
Однако установленная версия 3.2, и в моем php7.2 будут проблемы. Поскольку каждый() был оставлен, я изменю исходный код и заменю каждый() на foreach().
Результаты заключаются в следующем
Данные также хранятся в базе данных
Конечно, вы также можете снова получить конкретное содержимое страницы по URL-адресу. Здесь мы не проводим демонстрацию. Те, кому это интересно, могут осознать это сами.
Для получения дополнительной информации о PHP читатели, интересующиеся этим сайтом, могут ознакомиться со следующими темами: краткое описание навыков работы с процессами и потоками PHP, краткое описание навыков сетевого программирования PHP, вводный курс базового синтаксиса PHP, полная коллекция навыков работы с массивами PHP, краткое описание использования строк PHP “Руководство по работе с базой данных PHP + MySQL” и “Краткое описание навыков работы с общей базой данных PHP”.
Я надеюсь, что эта статья будет полезна для программирования на PHP.