需求:初步搭建服务器
服务器一台(linux)+自己安装PHP环境,有PHP环境就行了,apache,nginx,不影响
开始:
curl -Ss http://www.workerman.net/check.php | php
查看服务器是否有安装workerman的环境
如果出现这个情况就OK。一般都是posix没有。
安装posix
yum search php56w-process
查找此扩展
yum install php56w-process.x86_64
安装此扩展
php -m|grep posix
查看是否安装成功
再运行查看服务器是否有安装workerman的环境的命令,上面有。
安装GatewayWorker ,http://doc2.workerman.net/。官网地址。
安装到随便哪个目录都行,建议还是web目录最好。
然后按照官网方式启动。
重点:1.Events.php(在application/yourapp)主要逻辑编写在这个里面,另外三个是注册文件,启动文件,业务启动文件
2.start_gateway里面有默认端口。测试不用改,正式运营要改。我这里是做测试,默认8282,去阿里云服务器安全组开启此端口
3.开启phpstudy,新建一个index.html页面
<!DOCTYPE html>
<html>
<head>
<title>demo</title>
</head>
<body>
1231
</body>
<script type="text/javascript">
var ws = new WebSocket("ws://你的服务器IP地址:8282");
console.log(ws);
ws.onopen = function(evt){ //绑定连接事件
ws.send("hello workerman!");
};
ws.onmessage = function(evt) {//绑定收到消息事件
console.log("Received Message: " + evt.data);
};
</script>
</html>
访问此地址,去服务器查看,就会有信息弹出。
每请求一次就会出现一个ID。
4.每当修改了一次GatewayWorker的代码,不管是var_dump或者echo了都要重新启动一次GatewayWorker服务。
php start.php restart
好了,大功告成。具体操作按照自己实际业务逻辑来就行。
events.php
<?php
use \GatewayWorker\Lib\Gateway;
use \GatewayWorker\Lib\Db;
/**
* 主逻辑
* 主要是处理 onConnect onMessage onClose 三个方法
* onConnect 和 onClose 如果不需要可以不用实现并删除
*/
class Events
{
/**
* 新建一个类的静态成员,用来保存数据库实例
*/
public static $db = null;
/**
* 进程启动后初始化数据库连接
*/
public static function onWorkerStart($worker)
{
//self::$db = new \Workerman\MySQL\Connection('120.79.57.160', '3306', 'root', 'TPshop@2018', 'tp_kefu');//线上
self::$db = new \Workerman\MySQL\Connection('127.0.0.1', '3306', 'root', 'root', 'b2t_im');//本地
}
/**
* 当客户端发来消息时触发
* @param int $client_id 连接id
* @param mixed $message 具体消息
*/
public static function onMessage($client_id, $data)
{
$message = json_decode($data, true);
$message_type = $message['type'];
//Events::setLogs(json_encode($message));//写日志
switch ($message_type) {
case 'init':
$uid = $message['id'];
$_SESSION = array(
'username' => $message['username'],
'avatar' => $message['avatar'],
'id' => $uid,
'sign' => $message['sign'],
);
// 将当前链接与uid绑定
Gateway::bindUid($client_id, $uid);
$db1 = self::$db; //数据库链接
// 问题:如何区分客服和客户id?
if (substr($uid,0,4) != 'kefu') { //客户发消息过来
$userid = $uid;
$storeid = $message['storeid'] ? $message['storeid'] : 1;
if(substr($uid,0,2) == 'hy'){ //如果是会员 修改上线状态
$hy = explode('_',$uid);
$db1->update('tp_kf_custom')->cols(array('status'=>1))->where('uid = '.$hy[1])->query();
}
//查找配置表 获取一条数据
$config = $db1->select('*')->from('tp_kf_config')->where('store_id = '.$storeid)->row();
if($config){ //存在配置
//匹配逻辑说明 1.优先匹配最近曾服务过的客服,不在线 匹配紧急联系人
$ownership = $db1->query('SELECT k.* FROM tp_kf_ownership c LEFT JOIN tp_kf_kefu k ON k.id=c.kefu_id WHERE c.client_id ="'.$userid.'" AND c.store_id ='.$storeid.' AND c.is_delete = 0 AND k.Auditing = 1 AND k.is_delete = 0 ORDER BY c.id desc LIMIT 1');
$kefu = array();
if($ownership){ //存在归属人 老客户
$ownership = $ownership[0];
if($ownership['status'] == 1){ //在线
$kefu = $ownership;
}else{ //不在线
if($ownership['second_contact_id']){ //设置了紧急联系人
$second_contact = $db1->select('*')->from('tp_kf_kefu')->where('id ='.$ownership['second_contact_id'])->row();
if($second_contact && $second_contact['status'] == 1){ //紧急联系人在线
$kefu = $second_contact;
}else{ //紧急联系人不在线 该客户离线消息
$kefu = $ownership;
}
}else{ //未设置紧急联系人 该客服的离线消息
$kefu = $ownership;
}
}
}else{ //新客户
if($config['type'] == 1){ //随机匹配客服
//2.没有被客服接待过,随机匹配在线客服,木有,匹配机器人
$kefu_data = $db1->query('select * from tp_kf_kefu where storeid='.$storeid.' and status=1 and Auditing = 1 and is_delete = 0 order by rand() limit 1');
if($kefu_data){ //存在在线客服
$kefu = $kefu_data[0];
}else{ //不存在在线客服
//查看机器人设置
$robot = $db1->select('*')->from('tp_kf_robot')->where('storeid = '.$storeid.' and status = 1')->row();
if(!$robot){ //不存在或者机器人未开启 随机匹配不在线客服 发离线消息
$kefu = $db1->query('select * from tp_kf_kefu where storeid='.$storeid.' and Auditing = 1 and is_delete = 0 order by rand() limit 1');
if($kefu) $kefu = $kefu[0];
}
}
}elseif($config['type'] == 2){ //顺序匹配客服
//没有被客服接待过,顺序匹配客服,若匹配的客服不在线 匹配紧急联系人
$kefu_id = explode(',',$config['match_order']);
$next_id = $config['now'] + 1;
if(count($kefu_id) <= $next_id){ //说明已到达最后 从新开始
$next_id = 0;
}
$kefu = $db1->select('*')->from('tp_kf_kefu')->where('id = '.$kefu_id[$next_id])->row();
if($kefu['status'] != 1){ //假如不在线 匹配紧急联系人
if($kefu['second_contact_id']){
$second_contact = $db1->select('*')->from('tp_kf_kefu')->where('id ='.$kefu['second_contact_id'])->row();
if($second_contact && $second_contact['status'] == 1){ //紧急联系人在线
$kefu = $second_contact;
}
}
}
//修改config表 下次匹配另外客服
$row_count = $db1->update('tp_kf_config')->cols(array('now'=>$next_id))->where('id = '.$config['id'])->query();
}
}
//匹配到客服
if($kefu){
//客服 init消息
$log_message1 = [
'message_type' => 'init',
'data' => [
'kefu_id' => 'kefu'.$kefu['id'],
'kefu_name' => $kefu['user_name'],
'kefu_avatar' => $kefu['avatar'],
'kefu_sign' => $kefu['sign'],
'kefu_storeid' => $kefu['storeid'],
'kefu_store_name' => $kefu['store_name'],
]
];
Gateway::sendToUid($uid, json_encode($log_message1));
//店铺提示语推送
$store_slogan = $db1->select('sl.slogan,s.store_name,s.storeid,s.avatar')->from('tp_kf_slogan sl')->leftJoin('tp_kf_store s','sl.storeid = s.storeid')->where('sl.storeid = '.$storeid.' AND sl.slogan_status = 1 AND sl.auditing = 1 AND sl.is_delete = 0 AND sl.kefuid = 0')->row();
if($store_slogan){
$log_message2 = [
'message_type' => 'chatMessage',
'data' => [
'username' => $store_slogan['store_name'],
'name' => $store_slogan['store_name'],
'id' => 'kefu'.$kefu['id'],
'content' => $store_slogan['slogan'],
'type' => 'friend',
'timestamp' => time() * 1000,
'storeid' => $store_slogan['storeid'],
'avatar' => $store_slogan['avatar'],
]
];
Gateway::sendToUid($uid, json_encode($log_message2));
}
//客服提示语推送
$kefu_slogan = $db1->select('sl.slogan,k.user_name,k.storeid,k.avatar')->from('tp_kf_slogan sl')-> leftJoin('tp_kf_kefu k','sl.kefuid = k.id')->where('sl.storeid = '.$storeid.' AND sl.slogan_status = 1 AND sl.auditing = 1 AND sl.is_delete = 0 AND sl.kefuid = '.$kefu['id'])->row();
if($kefu_slogan){
$log_message3 = [
'message_type' => 'chatMessage',
'data' => [
'username' => $kefu_slogan['user_name'],
'name' => $kefu_slogan['user_name'],
'id' => 'kefu'.$kefu['id'],
'content' => $kefu_slogan['slogan'],
'type' => 'friend',
'timestamp' => time() * 1000,
'storeid' => $kefu_slogan['storeid'],
'avatar' => $kefu_slogan['avatar'],
]
];
Gateway::sendToUid($uid, json_encode($log_message3));
}
//查询最近1周有无需要推送的离线信息 发送历史记录信息 客服发给客户的离线消息
$time = time() - 7 * 3600 * 24;
$resMsg = $db1->select('id,from_id,from_name,timeline,content')->from('tp_kf_chatlog')
->where("kefu_id = '{$uid}' and timeline > {$time} and need_send = 1 and from_id = 'kefu{$kefu['id']}'" )
->query();
if (!empty($resMsg)) {
foreach ($resMsg as $key => $vo) {
$log_message = [
'message_type' => 'chatMessage',
'data' => [
'username' => $vo['from_name'],
'name' => $vo['from_name'],
'id' => $vo['from_id'],
'content' => htmlspecialchars($vo['content']),
'type' => 'friend',
'timestamp' => $vo['timeline'] * 1000,
'avatar' => $kefu['avatar'],
]
];
// sleep(5);
Gateway::sendToUid($uid, json_encode($log_message));
//设置推送状态为已经推送
$db1->query("UPDATE `tp_kf_chatlog` SET `need_send` = '0' WHERE id=" . $vo['id']);
}
}
//如果是商家会员 创建客服归属
if(substr($uid,0,2) == 'hy'){
$ownership = $db1->query('select * from tp_kf_ownership where client_id = "'.$uid.'" and store_id = '.$storeid.' and is_delete = 0');
//统计客服归属人数
//$total = $db1->select('count(*) as total')->from('tp_kf_ownership')->where('kefu_id = '.$kefu['id'].' and is_delete = 0')->single();
//|| $total < $config['ownership_person_num']
if(!$ownership){ //不存在 添加数据
$insert_id = $db1->insert('tp_kf_ownership')->cols(array(
'store_id'=> $storeid,
'client_id'=>$uid,
'kefu_id'=> $kefu['id'],
'is_delete'=>0,
'add_time'=> time(),
//'del_time'=> time() + $config['ownership_time']*24*60*60,
//'status'=> 0
))->query();
}
}
}else{ //匹配机器人
// 获取机器人基本信息
$robot = $db1->query('select b.*,s.store_name from tp_kf_robot b LEFT JOIN tp_kf_store s ON b.storeid = s.storeid where b.storeid = '.$storeid);
if($robot){ //如果该店铺设置了机器人 机器人提示
$robot = $robot[0];
//机器人信息
$robot_message = [
'message_type' => 'init',
'data' => [
'kefu_id' => 'rb'.$robot['id'],
'kefu_name' => $robot['robot_name'],
'kefu_avatar' => $robot['avatar'],
'kefu_sign' => '我是机器人'.$robot['robot_name'].',很高兴为您服务',
'kefu_storeid' => $robot['storeid'],
'kefu_store_name' => $robot['store_name'],
]
];
$robot_menu = $db1->query('select * from tp_kf_attr_question where storeid = '.$storeid.' and pid = 0' );
$html = '';
$html .= '【热门问题】<br />';
$html .= "<pre><span class='rb-menu'>";
foreach ($robot_menu as $k => $v) {
$html .= ++$k."、<a href='javascript:;' class='rb-menu-a' style='cursor:pointer;color:blue;' onclick='rbMenu(this)'>".$v['name']."</a><br />";
}
$html .= "</span></pre>";
$rbtime = time();
//机器人问候语
$robot_slogan = [
'message_type' => 'chatMessage',
'data' => [
'username' => $robot['robot_name'],
'name' => $robot['robot_name'],
'id' => 'rb'.$robot['id'],
'content' =>'您好,我是机器人'.$robot['robot_name'].',很高兴为您服务',
'type' => 'friend',
'timestamp' => $rbtime * 1000,
'avatar' => $robot['avatar'],
]
];
//机器人菜单
$robot_menu = [
'message_type' => 'chatMessage',
'data' => [
'username' => $robot['robot_name'],
'name' => $robot['robot_name'],
'id' => 'rb'.$robot['id'],
'content' => $html,
'type' => 'friend',
'timestamp' => $rbtime * 1000,
'avatar' => $robot['avatar'],
]
];
//消息发送
Gateway::sendToUid($uid, json_encode($robot_message));
Gateway::sendToUid($uid, json_encode($robot_slogan));
Gateway::sendToUid($uid, json_encode($robot_menu));
}
}
}
}else{ // 客服离线消息推送
sleep(1);
$id = substr($uid,4);
//客户设置为已登录IM
$db1->query("update `tp_kf_kefu` set status = 1 where id=" . $id);
//查询最近1周有无需要推送的离线信息
$time = time() - 7 * 3600 * 24;
$resMsg = $db1->select('id,from_id,from_name,timeline,content')->from('tp_kf_chatlog')
->where("kefu_id= '{$uid}' and timeline > {$time} and need_send = 1" )
->query();
if (!empty($resMsg)) {
foreach ($resMsg as $key => $vo) {
$log_message = [
'message_type' => 'chatMessage',
'data' => [
'username' => $vo['from_name'],
'name' => $vo['from_name'],
'id' => $vo['from_id'],
'content' => $vo['content'],
'type' => 'friend',
'timestamp' => $vo['timeline'] * 1000,
'avatar' => $message['avatar'],
]
];
Gateway::sendToUid($uid, json_encode($log_message));
//设置推送状态为已经推送
$db1->query("UPDATE `tp_kf_chatlog` SET `need_send` = '0' WHERE id=" . $vo['id']);
}
}
}
// 通知上线
$online_message = [
'message_type' => 'online',
'id' => $uid,
];
Gateway::sendToAll(json_encode($online_message));
return;
break;
case 'chatMessage':
$db1 = self::$db; //数据库链接
// 聊天消息
$type = $message['data']['to']['type'] ? $message['data']['to']['type'] : 'friend';
$to_id = $message['data']['to']['id'];
$minename = $_SESSION['username'];
$toname = $message['data']['to']['username'];
$storeid = $message['data']['to']['storeid'];
$store_name = empty($message['data']['to']['store_name']) ? '' : $message['data']['to']['store_name'];
$uid = $_SESSION['id'];
$chat_message = [
'message_type' => 'chatMessage',
'data' => [
'username' => $_SESSION['username'],
'name' => $_SESSION['username'],
'avatar' => $_SESSION['avatar'],
'id' => $type === 'friend' ? $uid : $to_id,
'type' => $type,
'content' => htmlspecialchars($message['data']['mine']['content']),
'timestamp' => time() * 1000,
]
];
// 加入聊天log表
$param = [
'from_id' => $uid,
'kefu_id' => $to_id,
'from_name' => $minename,
'to_name' => $toname,
'content' => htmlspecialchars($message['data']['mine']['content']),
'timeline' => time(),
'storeid' => $storeid,
'store_name' => $store_name,
];
switch ($type) { // 私聊
case 'friend':
if (substr($to_id,0,2)=='rb') { // 如果是机器人接待,直接回复
// 机器人回复
if ($message['data']['mine']['content'] == '菜单') { //输入菜单
$robot_menu = $db1->query('select * from tp_kf_attr_question where storeid = '.$storeid.' and pid = 0' );
$html = '<h3>【热门问题】</h3><br />';
$html .= "<pre><span class='rb-menu'>";
foreach ($robot_menu as $k => $v) {
$html .= ++$k."、<a href='javascript:;' class='rb-menu-a' style='cursor:pointer;color:blue;' onclick='rbMenu(this)'>".$v['name']."</a><br />";
}
$html .= "<br /></span></pre>";
$rbtime = time();
$robot_menu = [
'message_type' => 'chatMessage',
'data' => [
'username' => $toname,
'name' => $toname,
'id' => $to_id,
'content' => $html,
'type' => 'friend',
'timestamp' => $rbtime * 1000,
'avatar' => $message['data']['to']['avatar'],
]
];
Gateway::sendToUid($uid, json_encode($robot_menu));
}else { //输入的不是“菜单”
// 回复基本逻辑
// 1.先从分类表寻找子分类
// 2.如若找不到子分类则去问题表寻找问题
// 3.问题表找不到问题时则回复:“抱歉 ,没有找到您的相关问题”
$attr_id = $db1->query("select id from tp_kf_attr_question where name like '%".$message['data']['mine']['content']."%' and storeid=".$storeid);//取得id
if ($attr_id) { //找到客户输入的问题
$ques = $db1->query("select * from tp_kf_attr_question where pid =".$attr_id[0]['id']." and storeid = ".$storeid);
if ($ques) { //找到子级问题
$question['content'] = '';
$question['content'] .= '<br /><span style="font-size:26px;color:#06bd38;">答:</span>'.$question['content'];
$question['content'] .= '您好,关于“'.$message['data']['mine']['content'].'”我们有以下几点,请您留意关注<br /><br /><hr style="height:1px;border:none;border-top:1px solid #ccc8c8;" /><br />';
$question['content'] .= "<pre><span class='rb-menu'>";
foreach ($ques as $k => $v) {
$question['content'] .= ++$k."、<a href='javascript:;' class='rb-menu-a' style='cursor:pointer;color:blue;' onclick='rbMenu(this)'>".$v['name']."</a><br />";
}
$question['content'] .= "<br /></span></pre>";
}else { //找答案
$sql = "select * from tp_kf_question where pid =".$attr_id[0]['id']." and storeid=".$storeid;
$msg = $db1->query($sql);
if (empty($msg)) { //未找到答案
$question['content'] = '<br /><span style="font-size:26px;color:#06bd38;">答:</span>抱歉 ,没有找到您的相关问题1';
}else{ //找到答案
$msg = $msg[0];
$question = $db1->query('select * from tp_kf_answer where que_id='.$msg['id']);
$question = $question[0];
// 拼接外部链接
if (!empty($msg['link'])) {
$question['content'] .= '。请点击了解<a href="'.$msg['link'].'" target="_blank" style="color:blue;" >更多</a>';
}
$question['content'] = '<br /><span style="font-size:26px;color:#06bd38;">答:</span>'.$question['content'];
}
// 拼接菜单
$ques = $db1->query("select * from tp_kf_attr_question where pid = 0 and storeid = ".$storeid);
if ($ques) {
$question['content'] .= '<br /><br /><hr style="height:1px;border:none;border-top:1px solid #ccc8c8;" /><br />';
$question['content'] .= '感谢为您服务,您还可以咨询一下问题:<br />';
$question['content'] .= "<pre><span class='rb-menu'>";
foreach ($ques as $k => $v) {
$question['content'] .= ++$k."、<a href='javascript:;' class='rb-menu-a' style='cursor:pointer;color:blue;' onclick='rbMenu(this)'>".$v['name']."</a><br />";
}
$question['content'] .= "<br /></span></pre>";
}
}
}else { //未找到客户的问题
$sql = "select * from tp_kf_question where name like '%".$message['data']['mine']['content']."%' and storeid=".$storeid;
$msg = $db1->query($sql);
if (empty($msg)) {
$question['content'] = '<br /><span style="font-size:26px;color:#06bd38;">答:</span>抱歉 ,没有找到您的相关问题';
}else{
$msg = $msg[0];
$question = $db1->query('select * from tp_kf_answer where que_id='.$msg['id']);
$question = $question[0];
// 拼接外部链接
if (!empty($msg['link'])) {
$question['content'] .= '。请点击了解<a href="'.$msg['link'].'" target="_blank" style="color:blue;" >更多</a>';
}
}
$ques = $db1->query("select * from tp_kf_attr_question where pid = 0 and storeid = ".$storeid);
if ($ques) {
$question['content'] .= '<br /><br /><hr style="height:1px;border:none;border-top:1px solid #ccc8c8;" /><br />';
$question['content'] .= '感谢为您服务,您还可以咨询一下问题:<br />';
$question['content'] .= "<pre><span class='rb-menu'>";
foreach ($ques as $k => $v) {
$question['content'] .= ++$k."、<a href='javascript:;' class='rb-menu-a' style='cursor:pointer;color:blue;' onclick='rbMenu(this)'>".$v['name']."</a><br />";
}
$question['content'] .= "<br /></span></pre>";
}
}
// 编辑待发送信息
$robot_msg = [
'message_type' => 'chatMessage',
'data' => [
'username' => $toname,
'name' => $toname,
'avatar' =>$message['data']['to']['avatar'],
'id' => $to_id,
'type' => 'friend',
'content' => $question['content'],
'timestamp' => time() * 1000,
]
];
Gateway::sendToUid($uid, json_encode($robot_msg));
}
}else{ //客服接待
// 插入
if (empty(Gateway::getClientIdByUid($to_id))) {
$param['need_send'] = 1; //用户不在线,标记此消息推送
}
//聊天记录表 增数据
$db1->insert('tp_kf_chatlog')->cols($param)->query();
Gateway::sendToUid($to_id, json_encode($chat_message));
}
break;
case 'group':
break;
}
return;
break;
case 'ping':
return;
case 'suggest':
$db1 = self::$db; //数据库链接
return;
case 'addGroup':
//客服讨论群组
return;
break;
case 'addFriend':
//添加好友
$client_id = Gateway::getClientIdByUid($message['to_id']);//判断该用户是否在线
//用户在线才通知
if(!empty($client_id)){
$add_message = [
'message_type' => 'addFriend',
'data' => [
'username' => $message['username'],
'avatar' => $message['avatar'],
'id' => $message['id'],
'type' => 'friend',
'sign' => $message['sign'],
'groupid' => $message['groupid'],
]
];
Gateway::sendToClient($client_id['0'], json_encode($add_message));
}
return;
break;
//好友申请
case 'applyFriend':
$client_id = Gateway::getClientIdByUid($message['to_id']);
//用户在线才通知
if(!empty($client_id)){
$apply_message = [
'message_type' => 'applyFriend',
'data' => [
'id' => $message['mine_id']
]
];
Gateway::sendToClient($client_id['0'], json_encode($apply_message));
}
return;
break;
case 'delFriend':
//删除好友
$client_id = Gateway::getClientIdByUid($message['to_id']);
//用户在线才通知
if(!empty($client_id)){
$add_message = [
'message_type' => 'delFriend',
'data' => [
'id' => $message['del_id']
]
];
Gateway::sendToClient($client_id['0'], json_encode($add_message));
}
return;
break;
case 'online' :
//显隐切换 实时在好友面板上灰色与亮色切换
$db1 = self::$db; //数据库链接
// 在线切换状态
$friends = $db1->query("select `user_id` from `tp_kf_friend` where `type` = 1 and `friend_id` = " . substr($message['uid'],4));
if (!empty($friends)) {
foreach ($friends as $key => $vo) {
$user_client_id = Gateway::getClientIdByUid('kefu'.$vo['user_id']);
if (!empty($user_client_id)) {
$online_message = [
'message_type' => ('online' == $message['status']) ? 'online' : 'offline',
'id' => $message['uid'],
];
Gateway::sendToClient($user_client_id['0'], json_encode($online_message));
}
}
}
return;
break;
default:
return;
break;
}
}
/**
* 当用户断开连接时触发
* @param int $client_id 连接id
*/
public static function onClose($client_id)
{
//维持连接的worker退出才触发
$db1 = self::$db; //数据库链接
// 通知下线
$offline_message = [
'message_type' => 'offline',
'id' => $_SESSION['id'],
];
Gateway::sendToAll(json_encode($offline_message));
if (substr($_SESSION['id'],0,4)=='kefu') { //设置客服用户为退出状态
$id = substr($_SESSION['id'],4);
$db1->query("update `tp_kf_kefu` set `status` = 0 where id = " . $id);
}else{ //这里可以做客户退出操作,因为IM没有客户表,省略
$id = $_SESSION['id'];
//这里可以设置会员客户退出的操作
if(substr($id,0,2) == 'hy'){ //不是游客
$uid = explode('_',$id);
if(!empty($uid[1]) && is_numeric($uid[1])){
$db1->query("update `tp_kf_custom` set `status` = 0 where uid = " . $uid[1]);
}
}
}
}
/**
* 写日志
* @param string $world
*/
public static function setLogs($world = '')
{
$path = './';
$time = date('Ymd');
$file = fopen($path."$time.txt","a");
$txt = date("Y-m-d H:i:s") .$world."\r\n";
fwrite($file, $txt);
fclose($file);
}
}