} function progress($ch) { // infinite loop for (;;) { echo "still downloadin'...\n"; // the second argument to thread_message_queue_poll is a timeout // if it times out, it returns the string (not the constant) PHP_THREAD_POLL_TIMEOUT // this function is blocking (it waits until a message is recieved or timeout triggered) $var = thread_message_queue_poll($ch, 500); if ($var == 'done') { return; } } } foreach ($sites as $site) { echo "Starting download of {$site}!\n"; $threads[] = thread_create("get_url_threaded", $site); } // communication channel $ch = thread_message_queue_create(); // progress loop $progress = thread_create('progress', $ch); // wait for all threads to finish foreach ($threads as $thread) { thread_join($thread); } // tell progress to stop thread_message_queue_post($ch, 'done'); // we are done! echo "All downloads done!\n";
{ for (;;) { // receive the message from $ch $a = thread_message_queue_poll($ch); // TRIPLE COMPARISION IS IMPORTANT!!!! if ($a === 'PHP_THREAD_POLL_STOP') { break; } printf("thread %02d: %02s\n", $i, $a * 2); } sleep(2); printf("thread %02s is done.\n", $i); } $ch = thread_message_queue_create(); for ($i = 0; $i < 20; $i++) { $rs[] = thread_create('sub', $i, $ch); } for ($i = 0; $i < 20; $i++) { // send $i to $ch thread_message_queue_post($ch, $i); usleep(200000); } // threads are still waiting for a message. tell them that we are stopping thread_message_queue_stop($ch); // after threads recieve the stop message, they break out of the for loop and sleep echo "Done sending messages. Threads are sleeping for 2 seconds.\n"; foreach ($rs as $val) { // thread_join waits for the the thread to finish before continuing thread_join($val); } echo "All threads are complete.";
$gid != 1 and $subject = badword_filter($subject, $badword); $subject === FALSE and message(1, '标题中包含敏感关键词: ' . $badword); empty($message) and message(2, '内容不能为空' . $fid); $conf['seo_url_rewrite'] and $seo_url and thread_read_by_seo_url($seo_url) and message(4, '自定义的 URL 已经存在,请修改。'); // 这里可能有并发问题,seo_url 并非 UNIQUE KEY $gid != 1 and $message = xn_html_safe($message); $gid != 1 and $message = badword_filter($message, $badword); $message === FALSE and message(2, '内容中包含敏感关键词: ' . $badword); strlen($seo_url) > 128 and message(3, '自定义 URL 太长'); mb_strlen($subject, 'UTF-8') > 128 and message(1, '标题最长80个字符'); mb_strlen($message, 'UTF-8') > 2028000 and message(2, '内容太长'); // 检测是否灌水 thread_check_flood($gid, $fid, $subject) and message(1, '系统检测到您可能在灌水。'); $thread = array('fid' => $fid, 'uid' => $uid, 'sid' => $sid, 'subject' => $subject, 'message' => $message, 'time' => $time, 'longip' => $longip, 'sid' => $sid); $seo_url and $thread['seo_url'] = $seo_url; $tid = thread_create($thread, $pid); $pid === FALSE and message(1, '创建帖子失败'); $tid === FALSE and message(1, '创建主题失败'); $conf['ipaccess_on'] and ipaccess_inc($longip, 'threads'); if ($ajax) { ob_start(); $thread = thread_read($tid); $threadlist = array($thread); include './pc/view/thread_list_body.inc.htm'; $middle = ob_get_clean(); message(0, $middle); } else { message(0, '发帖成功'); } } // 处理 2.1 老版本 URL
{ echo "sleeping for 1 second to demo threading capabilities\n"; sleep(1); fwrite($fd, "what you sent: " . fgets($fd, 1024)); // cleanup, we don't want excess threads floating around. fclose($fd); unset($fd); echo "done sending response\n"; exit; } $ssock = stream_socket_server('tcp://127.0.0.1:9000'); assert($ssock !== false); // cool infinite loop for ($i = 0;; $i++) { // sockets are just references in the thread, not copies $csock[$i] = stream_socket_accept($ssock, -1); echo "caught connection, creating thread!\n"; if ($csock[$i]) { //var_dump($csock); $threads[] = thread_create('echoing', $csock[$i]); echo "done creating thread.\n"; } else { trigger_error('Invalid csock', E_USER_WARNING); } foreach ($threads as $thread) { // this doesn't even work! i hope it will in the future. however a better // solution would be for threads to clean themselves up. thread_cleanup($thread); } //thread_clean_finished(); }
<?php class TestThread { public function run() { self::static_print("hello from the thread"); $this->print_ln("hello from the thread"); } public function print_ln($text) { echo $text . "\n"; } public static function static_print($text) { $x = new TestThread(); $x->print_ln($text); } } $test = new TestThread(); thread_create('TestThread::static_print', "Ohai"); echo "Done\n";
<?php function print_char($char, $times) { for ($i = 0; $i < $times; $i++) { echo $char; } } echo "\nMASTER: starting threads\n"; thread_create('print_char', 'x', 2000, 50); thread_create('print_char', 'y', 2000, 50); echo "\nMASTER: done\n";
<?php function threaded_client_connection($i) { // make results come back in different order sleep(11 - $i); $fp = stream_socket_client("tcp://127.0.0.1:9000", $errno, $errstr, 30); if (!$fp) { echo "{$errstr} ({$errno})<br />\n"; } else { fwrite($fp, "hello from thread {$i}\n"); while (!feof($fp)) { echo fgets($fp, 1024); } fclose($fp); } } // create 10 different connections for ($i = 1; $i <= 10; $i++) { thread_create('threaded_client_connection', $i); }
<?php /* demonstrating the ability to memleak all over the place */ function doWork() { echo "hi there\n"; var_dump(memory_get_usage()); exit; } sleep(3); while ($i < 20) { thread_create('doWork'); usleep(50000); $i++; } sleep(3); exit;
// 全局的 uid $gid = $user['gid']; // 全局的 gid $header['title'] = $conf['sitename']; // 网站标题 $header['keywords'] = $conf['sitename']; // 关键词 $header['description'] = $conf['sitename']; // 描述 // 启动在线,将清理函数注册,不能写日志。 runtime_init(); online_init(); register_shutdown_function('online_save'); register_shutdown_function('runtime_save'); $fid = 1; $uid = 1; $subject = $message = 'test'; $seo_url = ''; // 检查总帖数 $forum1 = forum__read($fid); $user1 = user__read($uid); thread_create($fid, $uid, $subject, $message, $seo_url, $time, $longip); $forum2 = forum__read($fid); $user2 = user__read($uid); x('forum.threads', $forum1['threads'] + 1, intval($forum2['threads'])); x('user.threads', $user1['threads'] + 1, intval($user2['threads'])); // 资源清理,删除用户: function x($info, $a, $b) { echo "{$info}: ... " . ($a === $b ? 'true' : 'false' . ", " . var_export($a, 1) . ", " . var_export($b, 1)) . "\r\n"; }
<?php chdir('./'); define('DEBUG', 0); define('APP_NAME', 'bbs'); define('IN_SAE', class_exists('SaeKV')); $conf = @(include './conf/conf.php'); // 支持 SAE IN_SAE and (include './conf/sae.conf.php'); include './xiunophp/xiunophp.php'; include './model.inc.php'; $browser = get__browser(); check_browser($browser); runtime_init(); online_init(); for ($i = 1; $i < 1000; $i++) { $subject = '欢迎使用 Xiuno BBS 3.0 新一代论坛系统。' . $i; $message = '祝您使用愉快!'; $thread = array('fid' => 1, 'uid' => 1, 'subject' => $subject, 'message' => $message, 'seo_url' => '', 'time' => $time, 'longip' => $longip); $tid = thread_create($thread, $longip); for ($j = 0; $j < 10; $j++) { $post = array('tid' => $tid, 'uid' => 1, 'create_date' => $time, 'userip' => $longip, 'isfirst' => 0, 'message' => $message . rand(1, 10000)); $pid = post_create($post, 1); } if ($i % 100 == 0) { echo '.'; } } cron_run(1); echo '生成数据完毕';
$thread_type = 'folder'; $r = thread_create($lang, $user_id, $thread_name, $thread_title, $thread_type); dump($r); extract($r); // thread_id thread_number $thread_title = 'Test thread'; $thread_abstract = 'The test thread.'; $thread_cloud = 'test node'; $thread_image = '/files/images/testthread.png'; $r = thread_set($lang, $thread_id, $thread_name, $thread_title, $thread_type, $thread_abstract, $thread_cloud, $thread_image, false, false, false, false, false, false, true, true, true, true, true); dump($r); $r = thread_get($lang, $thread_id); dump($r); $thread_name = 'testanotherthread'; $thread_title = 'Test Another Thread'; $r = thread_create($lang, $user_id, $thread_name, $thread_title, false, 2); dump($r); $another_thread_id = $r['thread_id']; $r = thread_get($lang, $another_thread_id, false); dump($r); $r = thread_delete($another_thread_id); dump($r); $node_name = 'testnode'; $node_title = 'Test node'; $r = thread_create_node($lang, $user_id, $thread_id, $node_name, $node_title); dump($r); extract($r); // node_id node_number $another_node_name = 'anothertestnode'; $another_node_title = 'Another test node'; $r = thread_create_node($lang, $user_id, $thread_id, $another_node_name, $another_node_title, 1);
function threadeditall($lang, $clang) { global $supported_threads, $with_toolbar; if (!user_has_role('writer')) { return run('error/unauthorized', $lang); } $confirmed = false; $action = 'init'; if (isset($_POST['thread_create'])) { $action = 'create'; } else { if (isset($_POST['thread_delete'])) { $action = 'delete'; } else { if (isset($_POST['thread_confirmdelete'])) { $action = 'delete'; $confirmed = true; } else { if (isset($_POST['threadlist_reorder'])) { $action = 'reorder'; } } } } $new_thread_name = $new_thread_title = $new_thread_type = $new_thread_number = false; $old_thread_number = false; $p = false; switch ($action) { case 'init': case 'reset': break; case 'create': case 'delete': case 'reorder': if (isset($_POST['new_thread_title'])) { $new_thread_title = readarg($_POST['new_thread_title']); } if ($new_thread_title) { $new_thread_name = strtofname($new_thread_title); } if (isset($_POST['new_thread_number'])) { $new_thread_number = readarg($_POST['new_thread_number']); } if (isset($_POST['new_thread_type'])) { $new_thread_type = readarg($_POST['new_thread_type']); } if (isset($_POST['old_thread_number'])) { $old_thread_number = readarg($_POST['old_thread_number']); } if (isset($_POST['p'])) { $p = $_POST['p']; // DON'T readarg! } default: break; } $thread_list = array(); $r = thread_list($clang, false, false); if (!$r or count($r) != count($p)) { $p = false; } if ($r) { $pos = 1; $thread_url = url('threadedit', $lang); foreach ($r as $b) { $b['thread_url'] = $thread_url . '/' . $b['thread_id']; $b['pos'] = $p ? $p[$pos] : $pos; $thread_list[$pos] = $b; $pos++; } } $missing_new_thread_title = false; $missing_new_thread_name = false; $bad_new_thread_name = false; $missing_new_thread_type = false; $bad_new_thread_type = false; $bad_new_thread_number = false; $missing_old_thread_number = false; $bad_old_thread_number = false; switch ($action) { case 'create': if (!$new_thread_title) { $missing_new_thread_title = true; } if (!$new_thread_name) { $missing_new_thread_name = true; } else { if (!preg_match('#^[\\w-]{2,}$#', $new_thread_name)) { $bad_new_thread_name = true; } } if (!$new_thread_number) { $bad_new_thread_number = false; } else { if (!is_numeric($new_thread_number)) { $bad_new_thread_number = true; } else { if ($new_thread_number < 1 or $new_thread_number > count($thread_list) + 1) { $bad_new_thread_number = true; } } } if (!$new_thread_type) { $missing_new_thread_type = true; } else { if (!in_array($new_thread_type, $supported_threads)) { $bad_new_thread_type = true; } } break; case 'delete': if (!$old_thread_number) { $missing_old_thread_number = true; } else { if (!is_numeric($old_thread_number)) { $bad_old_thread_number = true; } else { if ($old_thread_number < 1 or $old_thread_number > count($thread_list)) { $bad_old_thread_number = true; } } } break; default: break; } $confirm_delete_thread = false; switch ($action) { case 'create': if ($missing_new_thread_title or $missing_new_thread_name or $bad_new_thread_name or $bad_new_thread_number or $missing_new_thread_type or $bad_new_thread_type) { break; } $user_id = user_profile('id'); $np = thread_create($clang, $user_id, $new_thread_name, $new_thread_title, $new_thread_type, $new_thread_number); if (!$np) { break; } extract($np); /* thread_id thread_number */ $thread_title = $new_thread_title; $thread_url = url('threadedit', $lang) . '/' . $thread_id; $pos = $thread_number; if ($thread_list) { foreach ($thread_list as &$tr) { if ($tr['thread_number'] >= $pos) { $tr['thread_number']++; } if ($tr['pos'] >= $pos) { $tr['pos']++; } } array_splice($thread_list, $pos - 1, 0, array(compact('thread_id', 'thread_title', 'thread_number', 'thread_url', 'pos'))); array_multisort(range(1, count($thread_list)), $thread_list); } else { $pos = 1; $thread_list = array($pos => compact('thread_id', 'thread_title', 'thread_number', 'thread_url', 'pos')); } break; case 'delete': if ($missing_old_thread_number or $bad_old_thread_number) { break; } if (!$confirmed) { $confirm_delete_thread = true; break; } $thread_id = $thread_list[$old_thread_number]['thread_id']; $r = thread_delete($thread_id); if (!$r) { break; } unset($thread_list[$old_thread_number]); foreach ($thread_list as &$b) { if ($b['pos'] >= $old_thread_number) { $b['pos']--; } } $old_thread_number = false; break; case 'reorder': if (!$p) { break; } $neworder = range(1, count($p)); array_multisort($p, SORT_NUMERIC, $neworder); $number = 1; $nl = array(); foreach ($neworder as $i) { $tr =& $thread_list[$i]; if ($tr['thread_number'] != $number) { thread_set_number($tr['thread_id'], $number); $tr['thread_number'] = $number; } $tr['pos'] = $number; $nl[$number++] = $tr; } $thread_list = $nl; break; default: break; } head('title', translate('threadall:title', $lang)); head('description', false); head('keywords', false); head('robots', 'noindex, nofollow'); $site_title = translate('title', $lang); $view = url('thread', $clang) . '?' . 'slang=' . $lang; $banner = build('banner', $lang, $with_toolbar ? compact('headline') : compact('headline', 'view')); $scroll = true; $toolbar = $with_toolbar ? build('toolbar', $lang, compact('view', 'scroll')) : false; $inlanguages = view('inlanguages', false, compact('clang')); $errors = compact('missing_new_thread_title', 'bad_new_thread_title', 'missing_new_thread_name', 'missing_new_thread_type', 'bad_new_thread_name', 'bad_new_thread_type', 'bad_new_thread_number', 'missing_old_thread_number', 'bad_old_thread_number'); $content = view('editing/threadeditall', $lang, compact('clang', 'site_title', 'inlanguages', 'supported_threads', 'thread_list', 'new_thread_title', 'new_thread_type', 'new_thread_number', 'old_thread_number', 'confirm_delete_thread', 'errors')); $output = layout('editing', compact('toolbar', 'banner', 'content')); return $output; }