-
Notifications
You must be signed in to change notification settings - Fork 0
Guidelines and best practises
As their name tells Console User Interface Framework. Just user interface issues. When you work with CUIF, you DO NOT have to link your application to your interface. Although you need a subclass of Application, it is a user interface application. Your real application must be isolated of your user interface implementation. Tomorrow you may use WebOS for give to user an web accesible UI. So, when things are done well, make It becomes an easy task.
Well. You must make your application isolated. Build it with a Object Oriented Schema. If you already have an application, make at least classes with static methods such as a facade for your application, or like an abstraction layer.
Is a good practise put your application behind a webservice or a socket level service. I want to recommend it, because with CUIF you can write esaily an socket server, and salodev
repo provides to you an abstraction class of socket client, useful for create socket level APIs
If you going to use an webservice or socket service, make an abstraction class for it. It will help you when be time of move the service of server, change its hostname, its port, or anyelse. I recommend that you use it with an static mehod.
This example demostrates how you can isolate your UI app of your real application:
class MyLoginWindow extends \cuif\Window {
public function init(array $params = array()) {
$this->user = $this->createInputBox(0, 1, 'Username');
$this->pass = $this->createInputBox(0, 2, 'Password');
$this->createButton(0,3, 'Login')->bind('press', function() {
MyService::Login($this->user->value, $this->pass->value);
});
}
}
Note that, on press "login" button, I am not making any query to database for validations and authentication. I delegates it to my real application. Because the login can becomes also form a web page.
Digging in MyService example class you can find other interesting things:
class MyService {
static private $_connection = null;
static public function Login($user, $pass) {
return self::Call('login', array($user, $pass));
}
static public function Call($serviceName, array $parameters = array()) {
$deferred = new \salodev\Deferred();
$conn = self::GetCreateConnection();
$string = json_encode(array($serviceName, $parameters));
$conn->writeAndReadAsync($string, function($return) use ($deferred) {
// Here you can validate format of service response, and look for any error,
// so you may reject $deferred instance.
$deferred->resolve($return);
});
return $deferred;
}
static public function GetCreateConnection() {
if (!self::$_connection) {
$conn = new \salodev\SocketClient();
$conn->open('tcp://127.0.0.1', 3000, 3000); // host, port, timeout.
self::$_connection = $conn;
}
return self::$_connection;
}
}
You may think that it is very large, but thinking that you will write MyService class one time, so is not. Plus, you can use MyService::Call()
directly, and not implementing a method for each controller of your application.
About the MyService::GetCreateConnection()
method, you can decide how save connection info: Harcoded into method, into a class constant, or defined into a config file, loaded at start application. I vote for last.
Since PHP is a OOP language, yet is not supporting all features of a well OOP language. Returning type declarations are available from PHP 7. For oldest versions, you may simulate it for your IDE with inline documentation. Example:
// PHP 7 style:
class MyService {
static public function CallService( /* ... */ ): \salodev\Deferred {
}
}
// PHP 5 style:
class MyService {
/**
* @return \salodev\Deferred
*/
static public function CallService( /* ... */ ) {
}
}
The second case is not useful for PHP, because I declared return type into a comment. But is useful for your ide that will parse it like a real return type declaration. It will help you to share code with other developers and they learn quikly what your application does.
Please, take care about it. Is pretty important to give a good user experience to your users. So what things blocks my program? Well... things like this and more:
- Sleep
- mysqli_query() // mysqli::query();
- curl
- file_get_contents
- readfile
- stream with blocking reads: sockets, file pointers, standard input
Please do not use it. Instead use
salodev
wrappers repo. There are many implementations OOP styled, that by default non blockes your program.
Use the Deferred class for return async values. Use Timer::Timeout(function() {/*your code*/}, $useconds);
instead sleep