forked from ElisDN/functional-php-parser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path17.php
122 lines (102 loc) · 3.55 KB
/
17.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
use Symfony\Component\DomCrawler\Crawler;
require __DIR__ . '/vendor/autoload.php';
#####################################################
function parallel_map(callable $func, array $items) {
$childPids = [];
$result = [];
foreach ($items as $i => $item) {
$newPid = pcntl_fork();
if ($newPid == -1) {
die('Can\'t fork process');
} elseif ($newPid) {
$childPids[] = $newPid;
if ($i == count($items) - 1) {
foreach ($childPids as $childPid) {
pcntl_waitpid($childPid, $status);
$sharedId = shmop_open($childPid, 'a', 0, 0);
$shareData = shmop_read($sharedId, 0, shmop_size($sharedId));
$result[] = unserialize($shareData);
shmop_delete($sharedId);
shmop_close($sharedId);
}
}
} else {
$myPid = getmypid();
echo 'Start ' . $myPid . PHP_EOL;
$funcResult = $func($item);
$shareData = serialize($funcResult);
$sharedId = shmop_open($myPid, 'c', 0644, strlen($shareData));
shmop_write($sharedId, $shareData, 0);
echo 'Done ' . $myPid . ' ' . formatUsage(memory_get_peak_usage()) . PHP_EOL;
exit(0);
}
}
return $result;
}
function first($array) {
return reset($array);
}
function reduce(callable $func, array $array, $initial = null) {
return array_reduce($array, $func, $initial);
}
function clearUrl($url) {
return preg_replace('#\&sid=.{32}#s', '', $url);
}
function formatUsage($memory) {
return number_format($memory / 1024 / 1024, 2, '.', ' ') . ' Mb';
}
#####################################################
function normalizeUrl($url) {
return 'http://yiiframework.ru/forum/'. ltrim($url, './');
}
function getHtml($url) {
$file = __DIR__ . '/cache/' . md5($url);
if (file_exists($file)) {
return file_get_contents($file);
} else {
$html = file_get_contents($url);
file_put_contents($file, $html);
return $html;
}
}
function crawler($url) {
return new Crawler(getHtml(normalizeUrl($url)));
}
function getForumMaxPageNumber($forumUrl) {
return max(
first(crawler($forumUrl)
->filter('div.action-bar.bar-top .pagination li:nth-last-of-type(2)')
->each(function (Crawler $link) {
return intval($link->text());
})),
1
);
}
function getForumPages($forumUrl) {
echo 'Forum pages for ' . clearUrl($forumUrl) . PHP_EOL;
return array_map(function ($number) use ($forumUrl) {
return $forumUrl . ($number > 1 ? '&start=' . (25 * ($number - 1)) : '');
}, range(1, getForumMaxPageNumber($forumUrl)));
}
function getForumPageTopics($forumPageUrl) {
echo 'Forum page topics for ' . clearUrl($forumPageUrl) . PHP_EOL;
return crawler($forumPageUrl)
->filter('ul.topiclist.topics li dl')
->each(function (Crawler $topic) {
$link = $topic->filter('div.list-inner a.topictitle');
return [
'title' => $link->html(),
'url' => $link->attr('href'),
'count' => intval($topic->filter('dd.posts')->text()) + 1,
];
});
}
$forumUrl = './viewforum.php?f=28';
$topics =
reduce('array_merge',
parallel_map('getForumPageTopics',
getForumPages($forumUrl)), []);
echo 'Done ' . formatUsage(memory_get_peak_usage()) . PHP_EOL;
echo clearUrl(print_r($topics[0], true));
echo PHP_EOL;