本文整理汇总了PHP中microtime函数的典型用法代码示例。如果您正苦于以下问题:PHP microtime函数的具体用法?PHP microtime怎么用?PHP microtime使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了microtime函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的PHP代码示例。
示例1: getRandomBytes
private function getRandomBytes($count)
{
$bytes = '';
if (function_exists('openssl_random_pseudo_bytes') && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
// OpenSSL slow on Win
$bytes = openssl_random_pseudo_bytes($count);
}
if ($bytes === '' && @is_readable('/dev/urandom') && ($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) {
$bytes = fread($hRand, $count);
fclose($hRand);
}
if (strlen($bytes) < $count) {
$bytes = '';
if ($this->randomState === null) {
$this->randomState = microtime();
if (function_exists('getmypid')) {
$this->randomState .= getmypid();
}
}
for ($i = 0; $i < $count; $i += 16) {
$this->randomState = md5(microtime() . $this->randomState);
if (PHP_VERSION >= '5') {
$bytes .= md5($this->randomState, true);
} else {
$bytes .= pack('H*', md5($this->randomState));
}
}
$bytes = substr($bytes, 0, $count);
}
return $bytes;
}
开发者ID:vkaran101,项目名称:sase,代码行数:31,代码来源:Bcrypt.php
示例2: getToken
function getToken($table, $campo, $uc = TRUE, $n = TRUE, $sc = TRUE, $largo = 15)
{
$db = new db_core();
$source = 'abcdefghijklmnopqrstuvwxyz';
if ($uc == 1) {
$source .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
if ($n == 1) {
$source .= '1234567890';
}
if ($sc == 1) {
$source .= '|@#~$%()=^*+[]{}-_';
}
$rstr = "";
while (true) {
$rstr = "";
$source = str_split($source, 1);
for ($i = 1; $i <= $largo; $i++) {
mt_srand((double) microtime() * 1000000);
$num = mt_rand(1, count($source));
$rstr .= $source[$num - 1];
}
if (!$db->isExists($table, $campo, $rstr)) {
break;
}
}
return $rstr;
}
开发者ID:centaurustech,项目名称:eollice,代码行数:28,代码来源:webservice.php
示例3: smsSend
/**
* @param $phone
* @param $code
* @return bool
* send sms to register&runner phone
*/
private function smsSend($phone, $code)
{
$account = "mt6724";
$password = "le44n8";
$time = microtime();
$time = explode(" ", $time);
$time = $time[1] + $time[0];
$time = number_format($time * 1000, 0, ".", "");
$timestamp = $time;
$access_token = md5($timestamp . $password);
$receive = $phone;
$smscontent = "你的验证码为{$code},有效期10分钟";
$str = "account={$account}×tamp={$timestamp}&access_token={$access_token}&receiver={$receive}&smscontent={$smscontent}&extcode=0";
$url = "http://121.42.11.93:8001/interface/sendSms";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
// post数据
curl_setopt($ch, CURLOPT_POST, 1);
// post的变量
curl_setopt($ch, CURLOPT_POSTFIELDS, $str);
$output = curl_exec($ch);
curl_close($ch);
$res = json_decode($output, TRUE);
if ($res['res_code'] == '0') {
return true;
} else {
return false;
}
}
开发者ID:TruemenHale,项目名称:DingdingCat,代码行数:38,代码来源:AccountController.class.php
示例4: quoteFromDir
function quoteFromDir($dir)
{
$amount = 0;
$index = 0;
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if (strpos($file, ".dat") != false) {
$len = strlen($file);
if (substr($file, $len - 4) == ".dat") {
$number = $this->getNumberOfQuotes($dir . "/" . $file);
$amount += $number;
$quotes[$index] = $amount;
$files[$index] = $file;
$index++;
}
}
}
srand((double) microtime() * 1000000);
$index = rand(0, $amount);
$i = 0;
while ($quotes[$i] < $index) {
$i++;
}
return $this->getRandomQuote($dir . "/" . $files[$i]);
}
return -1;
}
开发者ID:pombredanne,项目名称:tuleap,代码行数:27,代码来源:fortune.php
示例5: processemail
public static function processemail($emailsrc, $pdfout, $coverfile = '')
{
$combfilelist = array();
# Process the email
$emailparts = Mail_mimeDecode::decode(array('include_bodies' => true, 'decode_bodies' => true, 'decode_headers' => true, 'input' => file_get_contents($emailsrc), 'crlf' => "\r\n"));
# Process the cover if it exists
if ($coverfile !== '') {
$combfilelist[] = self::processpart(file_get_contents($coverfile), mime_content_type($coverfile));
}
# Process the parts
$combfilelist = array_merge($combfilelist, self::processparts($emailparts));
# Create an intermediate file to build the pdf
$tmppdffilename = sys_get_temp_dir() . '/e2p-' . (string) abs((int) (microtime(true) * 100000)) . '.pdf';
# Build the command to combine all of the intermediate files into one
$conbcom = str_replace(array_merge(array('INTFILE', 'COMBLIST'), array_keys(self::$driver_paths)), array_merge(array($tmppdffilename, implode(' ', $combfilelist)), array_values(self::$driver_paths)), self::$mime_drivers['gs']);
exec($conbcom);
# Remove the intermediate files
foreach ($combfilelist as $combfilename) {
unlink($combfilename);
}
# Write the intermediate file to the final destination
$intfileres = fopen($tmppdffilename, 'rb');
$outfileres = fopen($pdfout, 'ab');
while (!feof($intfileres)) {
fwrite($outfileres, fread($intfileres, 8192));
}
fclose($intfileres);
fclose($outfileres);
# Remove the intermediate file
unlink($tmppdffilename);
}
开发者ID:swk,项目名称:bluebox,代码行数:31,代码来源:emailtopdf.php
示例6: Log_display
/**
* Constructs a new Log_display object.
*
* @param string $name Ignored.
* @param string $ident The identity string.
* @param array $conf The configuration array.
* @param int $level Log messages up to and including this level.
* @access public
*/
function Log_display($name = '', $ident = '', $conf = array(), $level = PEAR_LOG_DEBUG)
{
if (!class_exists('G')) {
$realdocuroot = str_replace('\\', '/', $_SERVER['DOCUMENT_ROOT']);
$docuroot = explode('/', $realdocuroot);
array_pop($docuroot);
$pathhome = implode('/', $docuroot) . '/';
array_pop($docuroot);
$pathTrunk = implode('/', $docuroot) . '/';
require_once $pathTrunk . 'gulliver/system/class.g.php';
}
$this->_id = G::encryptOld(microtime());
$this->_ident = $ident;
$this->_mask = Log::UPTO($level);
if (isset($conf['error_prepend'])) {
$this->_error_prepend = $conf['error_prepend'];
} else {
$this->_error_prepend = ini_get('error_prepend_string');
}
if (isset($conf['error_append'])) {
$this->_error_append = $conf['error_append'];
} else {
$this->_error_append = ini_get('error_append_string');
}
if (isset($conf['linebreak'])) {
$this->_linebreak = $conf['linebreak'];
}
}
开发者ID:emildev35,项目名称:processmaker,代码行数:37,代码来源:display.php
示例7: invokeStats
private function invokeStats(array $options, RequestInterface $request, $startTime, ResponseInterface $response = null, $error = null)
{
if (isset($options['on_stats'])) {
$stats = new TransferStats($request, $response, microtime(true) - $startTime, $error, []);
call_user_func($options['on_stats'], $stats);
}
}
开发者ID:sunkangtaichi,项目名称:PHPAPPLISTION_START,代码行数:7,代码来源:StreamHandler.php
示例8: mapReduce
/**
* @param \Kbrw\RiakBundle\Model\Cluster\Cluster $cluster
* @param \Kbrw\RiakBundle\Model\Bucket\Bucket $bucket
* @param \Kbrw\RiakBundle\Model\MapReduce\Query $query
* @return mixed
*/
public function mapReduce($cluster, $query)
{
try {
$request = $this->getClient($cluster->getGuzzleClientProviderService(), $this->getConfig($cluster))->post();
$extra = array("method" => "POST");
$ts = microtime(true);
$body = $this->getSerializer()->serialize($query, "json");
$extra["serialization_time"] = microtime(true) - $ts;
$request->setBody($body, "application/json");
$response = $request->send();
if ($response->getStatusCode() === 200) {
$fqcn = $query->getResponseFullyQualifiedClassName();
if (!empty($fqcn)) {
$ts = microtime(true);
$content = $this->getSerializer()->deserialize($response->getBody(true), $fqcn, "json");
$extra["serialization_time"] = microtime(true) - $ts;
$this->logResponse($response, $extra);
return $content;
}
$this->logResponse($response, $extra);
return $response->getBody(true);
}
$this->logResponse($response, $extra);
} catch (CurlException $e) {
$this->logger->err("Riak is unavailable" . $e->getMessage());
throw new RiakUnavailableException();
} catch (\Exception $e) {
$this->logger->err("Unable to execute a mapreduce query. Full message is : \n" . $e->getMessage() . "");
}
return null;
}
开发者ID:shopping-adventure,项目名称:RiakBundle,代码行数:37,代码来源:RiakMapReduceServiceClient.php
示例9: testRegularUser
public function testRegularUser()
{
$originalUser = $this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface');
$user = new UserWrapped($originalUser, $this->apiUser);
$this->assertTrue($user->isEnabled());
$this->assertTrue($user->isAccountNonExpired());
$this->assertTrue($user->isAccountNonLocked());
$this->assertTrue($user->isCredentialsNonExpired());
$this->assertTrue($user->isEqualTo($this->getMock('Symfony\\Component\\Security\\Core\\User\\UserInterface')));
$originalUser->expects($this->once())->method('eraseCredentials');
$user->eraseCredentials();
$username = 'lolautruche';
$password = 'NoThisIsNotMyRealPassword';
$roles = array('ROLE_USER', 'ROLE_TEST');
$salt = md5(microtime(true));
$originalUser->expects($this->exactly(2))->method('getUsername')->will($this->returnValue($username));
$originalUser->expects($this->once())->method('getPassword')->will($this->returnValue($password));
$originalUser->expects($this->once())->method('getRoles')->will($this->returnValue($roles));
$originalUser->expects($this->once())->method('getSalt')->will($this->returnValue($salt));
$this->assertSame($username, $user->getUsername());
$this->assertSame($username, (string) $user);
$this->assertSame($password, $user->getPassword());
$this->assertSame($roles, $user->getRoles());
$this->assertSame($salt, $user->getSalt());
$this->assertSame($originalUser, $user->getWrappedUser());
}
开发者ID:Pixy,项目名称:ezpublish-kernel,代码行数:26,代码来源:UserWrappedTest.php
示例10: log
/**
* ログを出力する
*
* @access public
* @param int $level ログレベル(LOG_DEBUG, LOG_NOTICE...)
* @param string $message ログメッセージ(+引数)
*/
function log($level, $message)
{
if ($this->fp == null) {
return;
}
$microtime = microtime(true);
$sec = floor($microtime);
$msec = floor(($microtime - $sec) * 1000);
$prefix = sprintf('%s.%03d %s ', strftime('%Y/%m/%dT%H:%M:%S', $sec), $msec, $this->ident);
if (array_key_exists("pid", $this->option)) {
$prefix .= sprintf('[%d]', getmypid());
}
$prefix .= sprintf('(mem:%s)', number_format(memory_get_usage()));
$prefix .= sprintf('(%s): ', $this->_getLogLevelName($level));
if (array_key_exists("function", $this->option) || array_key_exists("pos", $this->option)) {
$tmp = "";
$bt = $this->_getBacktrace();
if ($bt && array_key_exists("function", $this->option) && $bt['function']) {
$tmp .= $bt['function'];
}
if ($bt && array_key_exists("pos", $this->option) && $bt['pos']) {
$tmp .= $tmp ? sprintf('(%s)', $bt['pos']) : $bt['pos'];
}
if ($tmp) {
$prefix .= $tmp . ": ";
}
}
fwrite($this->fp, $prefix . $message . "\n");
return $prefix . $message;
}
开发者ID:khsk,项目名称:ethnam,代码行数:37,代码来源:File.php
示例11: stop
/**
* Set a benchmark stop point.
*
* @param string benchmark name
* @return void
*/
public static function stop($name)
{
if (isset(self::$marks[$name]) and self::$marks[$name]['stop'] === FALSE) {
self::$marks[$name]['stop'] = microtime(TRUE);
self::$marks[$name]['memory_stop'] = function_exists('memory_get_usage') ? memory_get_usage() : 0;
}
}
开发者ID:Dirichi,项目名称:Ushahidi_Web,代码行数:13,代码来源:Benchmark.php
示例12: execute
public function execute(Request $request, $count, OutputInterface $out)
{
$client = new \Elasticsearch\Client(['hosts' => [$request->getHost()]]);
$response = new Response();
if ($this->clearCache) {
$this->clearCache($client, $out);
}
$helper = new ProgressHelper();
$helper->start($out, $count);
$start = microtime(true);
for ($i = 0; $i < $count; $i++) {
try {
$response->addSuccess($client->search($request->getParameters()));
} catch (\Exception $ex) {
$response->addFailure();
var_dump($ex->getMessage());
exit;
}
$helper->advance();
}
$helper->finish();
$response->setExternalTime(microtime(true) - $start);
try {
$response->setStats($client->indices()->stats([['index' => $request->getIndex()], 'groups' => [$request->getStatId()]]));
} catch (\Exception $ex) {
// nothing to do here
}
return $response;
}
开发者ID:audriusb,项目名称:elastic-benchmark,代码行数:29,代码来源:Client.php
示例13: checkAuth
function checkAuth($redirectIfNeeded)
{
// is the user already logged in?
if (isset($_SESSION["uid"]) && $_SESSION["uid"] != "") {
// yes, already logged in
return $_SESSION["uid"];
} else {
if ($redirectIfNeeded) {
// user is not logged in and needs to do so
// send to the login page
// pass the current URL so that we can come back here after login
$currentUrl = currentUrl();
// rawurlencode converts the string so it's safe to pass as a URL GET parameter
$urlOfLogin = "login.php?sendBackTo=" . rawurlencode($currentUrl) . "&cb=" . microtime(true);
// use a JavaScript redirect; FYI, there's also an http header (Location:) that
// can be used to redirect, but that MUST be sent before any HTML, and this
// function (checkAuth) might be called after some HTML is sent
echo "<script>location.replace('{$urlOfLogin}');</script>";
return "";
} else {
// user is not logged in, but whoever called this function doesn't care
return "";
}
}
}
开发者ID:IanMage1,项目名称:WhiteSpace,代码行数:25,代码来源:_header.php
示例14: update
/**
* Updates bar by printing \r and new bar
*
* @param $progress Current value of progress between 0 and value given on constructor
*/
public function update($progress)
{
$this->_times[] = microtime(true);
$done = $progress == 0 ? 0 : round($progress / $this->_max * $this->_maxLength);
$left = round((1 - $progress / $this->_max) * $this->_maxLength);
// current/max
$output = ' ' . sprintf('%' . strlen($this->_max) . 's/%s', $progress, $this->_max) . ' ';
// progressbar
$output .= '[' . str_repeat('=', $done != 0 ? $done - 1 : $done) . ($done > 0 ? '>' : '') . str_repeat('-', $left) . ']';
// percent
$output .= ' ' . sprintf('%6.2f', round($progress / $this->_max * 100, 2)) . "%";
// eta
// using http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
// averageSpeed = SMOOTHING_FACTOR * lastSpeed + (1-SMOOTHING_FACTOR) * averageSpeed
if (count($this->_times) > 2) {
$lastSpeed = $this->_times[count($this->_times) - 1] - $this->_times[count($this->_times) - 2];
if ($this->_averageSpeed == -1) {
$this->_averageSpeed = $lastSpeed;
}
$this->_averageSpeed = ProgressBar::SMOOTHING_FACTOR * $lastSpeed + (1 - ProgressBar::SMOOTHING_FACTOR) * $this->_averageSpeed;
$output .= ' ETA ' . $this->_mtime2str(round($this->_averageSpeed * ($this->_max - $progress)));
$output .= ' ' . date('H:i:s', time() + round($this->_averageSpeed * ($this->_max - $progress)));
}
echo "\r" . $output . ' ';
}
开发者ID:kehet,项目名称:php-cli-utils,代码行数:30,代码来源:ProgressBar.php
示例15: pay
public function pay()
{
$orderName = $_GET['orderName'];
if (!$orderName) {
$orderName = microtime();
}
$orderid = $_GET['orderid'];
if (!$orderid) {
$orderid = $_GET['single_orderid'];
}
$payHandel = new payHandle($this->token, $_GET['from'], 'daofu');
$orderInfo = $payHandel->beforePay($orderid);
if (!$orderInfo['price']) {
exit('必须有价格才能支付');
}
$orderInfo = $payHandel->afterPay($orderid, '');
$from = $payHandel->getFrom();
$this->redirect('/index.php?g=Wap&m=' . $from . '&a=payReturn&token=' . $orderInfo['token'] . '&wecha_id=' . $orderInfo['wecha_id'] . '&nohandle=1&orderid=' . $orderid);
}
开发者ID:kevicki,项目名称:pig,代码行数:25,代码来源:DaofuAction.class.php
示例16: transform
/**
* Creates a set of files from the initial data and returns them as key/value
* pairs, where the path on disk maps to name which each file should have.
* Example:
*
* [
* '/tmp/path/to/file/on/disk' => 'file.pdf',
* '/tmp/path/to/file/on/disk-2' => 'file-preview.png',
* ]
*
* @return array key/value pairs of temp files mapping to their names
*/
public function transform()
{
// Get uploaded image from tmp directory
$imagine = new \Imagine\Gd\Imagine();
$image = $imagine->open($this->data['tmp_name']);
// Get path to tmp directory
$tmpPathParts = explode(DS, $this->data['tmp_name']);
array_pop($tmpPathParts);
// remove filename from path
$tmpPath = implode(DS, $tmpPathParts);
// Process fullsize image
if ($this->isTooBig($image)) {
// Shrink image to max dimensions and save in tmp dir
$size = new \Imagine\Image\Box(2000, 2000);
$mode = \Imagine\Image\ImageInterface::THUMBNAIL_INSET;
$tmpFullsize = microtime() . $this->data['name'];
$image->thumbnail($size, $mode)->save($tmpPath . DS . $tmpFullsize);
$retval[$tmpPath . DS . $tmpFullsize] = $this->data['name'];
} else {
$retval[$this->data['tmp_name']] = $this->data['name'];
}
// Create thumbnail
$size = new \Imagine\Image\Box(200, 200);
$mode = \Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND;
$thumbFilename = $this->generateThumbnailFilename($this->data['name']);
$image->thumbnail($size, $mode)->save($tmpPath . DS . $thumbFilename);
$retval[$tmpPath . DS . $thumbFilename] = $thumbFilename;
return $retval;
}
开发者ID:PhantomWatson,项目名称:macc,代码行数:41,代码来源:Transformer.php
示例17: _microtime
/**
* Compute a version out of microtime(true)
*
* @return string $version
*/
protected function _microtime()
{
$version = microtime(true) - 1073741824;
// 31 bits
$version = str_replace('.', '', (string) $version);
return substr($version, 0, $this->accuracy);
}
开发者ID:hunde,项目名称:bsc,代码行数:12,代码来源:Microtime.php
示例18: spin
/**
* Causes the sleep until a condition is satisfied by the function $lambda when it returns a true value.
*
* @param Callable $lambda function to run
* @param int $wait time to wait for timeout, in milliseconds
* @param int $pause time to pause between iterations, in milliseconds
*
* @return bool
* @throws \Exception (when timeout occurs)
*/
public function spin($lambda, $wait = 5000, $pause = 250)
{
$e = null;
$time_start = microtime(true);
$time_end = $time_start + $wait / 1000.0;
while (microtime(true) < $time_end) {
$e = null;
try {
if ($lambda($this)) {
return true;
}
} catch (\Exception $e) {
// do nothing
}
usleep($pause);
}
$backtrace = debug_backtrace();
if (!array_key_exists('file', $backtrace[1])) {
$backtrace[1]['file'] = '[unknown_file]';
}
if (!array_key_exists('line', $backtrace[1])) {
$backtrace[1]['line'] = '[unknown_line]';
}
$message = "Timeout thrown by " . $backtrace[1]['class'] . "::" . $backtrace[1]['function'] . "()\n" . $backtrace[1]['file'] . ", line " . $backtrace[1]['line'];
throw new \Exception($message, 0, $e);
}
开发者ID:srinivasgowda097,项目名称:IntroToBehatExample,代码行数:36,代码来源:AbstractContext.php
示例19: timer
/**
* Measure time between two events
*
* First call should be to $key = Debug::timer() with no params, or provide your own key that's not already been used
* Second call should pass the key given by the first call to get the time elapsed, i.e. $time = Debug::timer($key).
* Note that you may make multiple calls back to Debug::timer() with the same key and it will continue returning the
* elapsed time since the original call. If you want to reset or remove the timer, call removeTimer or resetTimer.
*
* @param string $key
* Leave blank to start timer.
* Specify existing key (string) to return timer.
* Specify new made up key to start a named timer.
* @param bool $reset If the timer already exists, it will be reset when this is true.
* @return string|int
*
*/
public static function timer($key = '', $reset = false)
{
// returns number of seconds elapsed since first call
if ($reset && $key) {
self::removeTimer($key);
}
if (!$key || !isset(self::$timers[$key])) {
// start new timer
preg_match('/(\\.[0-9]+) ([0-9]+)/', microtime(), $time);
$startTime = doubleval($time[1]) + doubleval($time[2]);
if (!$key) {
$key = $startTime;
while (isset(self::$timers[$key])) {
$key .= ".";
}
}
self::$timers[$key] = $startTime;
$value = $key;
} else {
// return timer
preg_match('/(\\.[0-9]*) ([0-9]*)/', microtime(), $time);
$endTime = doubleval($time[1]) + doubleval($time[2]);
$startTime = self::$timers[$key];
$runTime = number_format($endTime - $startTime, 4);
$value = $runTime;
}
return $value;
}
开发者ID:avatar382,项目名称:fablab_site,代码行数:44,代码来源:Debug.php
示例20: newLogId
protected function newLogId($plan = 'c')
{
$dt = microtime(true);
list($s, $ms) = explode('.', $dt);
$s = $s - 1435680000;
//18446744073709551616
//17------------------ 18组服务器
//--1234567890-------- 时间戳
//------------sss----- 毫秒
//---------------12345 进程
switch ($plan) {
case 'a':
//plan-a 180组服务器,30几年后溢出,(每个请求需要一个进程处理至少1个毫秒,)
$this->plan = 'a';
return sprintf("%03d%09d%03d%05d", \Sooh\Base\Ini::getInstance()->get('ServerId', 0), $s, substr($ms, 0, 3), getmypid());
case 'b':
//plan-b 18组服务器, 300年后溢出, (每个请求需要一个进程处理至少1个毫秒,)
$this->plan = 'b';
return sprintf("%02d%010d%03d%05d", \Sooh\Base\Ini::getInstance()->get('ServerId', 0), $s, substr($ms, 0, 3), getmypid());
case 'c':
//plan-c 18组服务器, 30年后溢出, (每个请求需要一个进程处理至少0.1个毫秒,)
$this->plan = 'c';
return sprintf("%02d%09d%04d%05d", \Sooh\Base\Ini::getInstance()->get('ServerId', 0), $s, substr($ms, 0, 4), getmypid());
default:
throw new \Sooh\Base\ErrException('unknown support log-guid-generate');
}
}
开发者ID:hillstill,项目名称:sooh,代码行数:27,代码来源:Data.php
注:本文中的microtime函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论