I am working on a Web chat application. In the app, users can run commands (such as /nick, /msg, etc) by starting with a / and then typing the command followed by parameters. For example, if someone wanted to change their username to "foobar", they would enter this in:
/whois foobar
However, I cannot think of a good way to organize the code for this. This is what I have so far:
In User.php
function User_command(array $args)
{
$command = $args['command'];
list($command_name, $command_parameters) = explode(' ', $command, 2);
$command_name = str_replace('/', '', strtolower($command_name));
$result = Command::process($command_name, $command_parameters);
if (!$result)
return responseFailure();
addQueueEntry($result['json'], $result['user_id'], $result['room_id'], $result['added_by']);
return responseSuccess();
}
* In Command.php *
class Command
{
public function process($command, $parameters)
{
$method = 'MinteCommand_' . $command;
if (function_exists($method))
return $method($parameters);
return null;
}
}
/* Note: When implementing commands, you must specify all fields for $response */
/* If you don't, then they might not work correctly or as intended. */
function MinteCommand_notice($message)
{
$response = array();
$response['json'] = array('addChatNotice' => $message);
$response['user_id'] = null;
$response['room_id'] = MINTE;
$response['added_by'] = SYSTEM;
return $response;
}
function MinteCommand_announce($message)
{
$response = array();
$response['json'] = array('addChatAnnouncement' => $message);
$response['user_id'] = null;
$response['room_id'] = MINTE;
$response['added_by'] = SYSTEM;
return $response;
}
function MinteCommand_announcement($message)
{
// Command "announcement" is an alternative spelling for command "announce"
return MinteCommand_announce($message);
}
function MinteCommand_clear($message)
{
$response = array();
$response['json'] = array('clearChat' => $message);
$response['added_by'] = SYSTEM;
$response['user_id'] = MINTE;
$response['room_id'] = null;
return $response;
}
function MinteCommand_whois($username)
{
$response = array();
$response['added_by'] = 'SYSTEM';
$query = DB::query('SELECT ip_address, user_agent, last_activity, room_id FROM mt_users
WHERE username = ? LIMIT 1', $username);
$exists = $query['num_rows'] > 0;
$ip_address = $user_agent = $last_activity = $room_id = "";
if ($exists)
{
$row = $query['rows'][0];
$ip_address = $row['ip_address'];
$user_agent = $row['user_agent'];
$last_activity = $row['last_activity'];
$room_id = $row['room_id'];
}
$response['json'] = array('addChatNotice' => !$exists ? 'User ' . $username . ' does not exist' :
'[' . $username . '] ' . $ip_address . '/' . $user_agent . ', last_activity=' . $last_activity . ', room_id=' . $room_id);
$response['added_by'] = SYSTEM;
$response['user_id'] = MINTE;
$response['room_id'] = null;
return $response;
}
function MinteCommand_msg($args)
{
list($username, $message) = explode(' ', $args, 2);
}
How can I go about improving the code and making it more organized and elegant? In total there will be around 30 commands.
-
\$\begingroup\$ Just a note that you really want to whitelist the possible commands that can match, to be secure. \$\endgroup\$Kzqai– Kzqai2011年07月20日 16:27:06 +00:00Commented Jul 20, 2011 at 16:27
1 Answer 1
Just an idea, but maybe this will help you from a manageability point of view:
public function process($command, $parameters) {
$method = 'MinteCommand_' . $command;
$methodFile = dirname(__FILE__) . 'commands/' . $method . ".php";
if (file_exists($methodFile)) {
require_once($methodFile);
if (function_exists($method)) {
return $method($parameters);
} else {
throw "invalid function";
}
} else {
throw "invalid function file";
}
}
The only benefit to this is that you simply create a new file with the new command (function) inside of that file and it'll automatically search for it if the command is issued. One caveat will be the limit on the number of commands you can have is a limit on the number of files you can have in a single directory on the filesystem...
Note The code may not be perfect from a syntax point of view. It's just to give you the general idea / concept.
-
2\$\begingroup\$ You cannot throw strings. \$\endgroup\$phant0m– phant0m2011年07月11日 21:58:45 +00:00Commented Jul 11, 2011 at 21:58
-
\$\begingroup\$ It was to provide a general suggestion .. see the Note in the post... \$\endgroup\$sdolgy– sdolgy2011年07月12日 05:40:17 +00:00Commented Jul 12, 2011 at 5:40