Home  Support Page  The Manual

Basics

Contents

Scope of this document

This document is intended to cover the basics.

Encapsulation

Phoebius framework is object-oriented. This means that classes here are everything. We really love how C# and Java helps us to solve the dependencies, and hate the tons of include's and require's we need to write in PHP. Thus we decided to oversimplify this:

  1. you do not need to include scripts with classes you wish to use;
  2. class files must be defined in a separate file which is located anywhere under the directory which is specified inside the include_path. A file naming pattern is <ClassName>.class.php (case-sensitive!).
So, to define a new class, say, MyController, it is reasonable to put it within $app/lib/Mvc/MyController.class.php and it will be found automatically on it's first usage (because $app/lib is added to include_path by default).

Then a class loader, that is initialized in core init-script, takes care about the look up.

Fail-save code

An application flow is exception-centric: each PHP's error/warning/notice is replaced with an exception object. Such a concept helps to avoid tons of unnoticeable inconsistencies (like an access to undefined index of an array) and thus making the usage of an internal PHP function strong enough and unambiguous. The following example proves that you won't forget to do the check:

try {
	// suppressing errors via "@" won't help you here wrt. error verbosity
	unlink('/path/to/nonexistent.file');
}
catch (ExecutionContextException $e) {
	// handle this gracefully
}
Of course, this functionality can be explicitly turned off when using a third-party library that does not know about the exceptions or ignores notices and warnings (e.g., PEAR).

Phoebius defines two exceptions that are used to wrap internal errors:

Assertions

In some cases you cannot rely on type-checks only: there are a lot of cases when you need to be sured that the control flow is predictable. This is true especially for loosely-typed languages.

For this reasons Phoebius introduces an assertion module: a set of easy-to-use routines that may be used in every corner case. They are wrapped by an Assert class. Each of the public static method accepts an expression to assert, the message to show if assertion fails, and an optional arguments to be interpolated within a message through the sprintf call. For example:

function setGreedy($flag) {
	Assert::isBoolean(
		$flag,
		'greedyness should be boolean, %s is given',
		TypeUtils::getName($flag) // may name a class, a scalar or even a null
	);
	
	Assert::isTrue(
		$this->mayHaveGreedyNess,
		'you cannot set greedyness here'
	);
	
	...
}

Assert gives the following methods to assert an expressions:

  • isTrue, isFalse to check whether expression is true or false
  • isCallback to determine whether an expression is callable
  • isEmpty, isNotEmpty to determine whether expression is empty or not (empty() operator is used, so all types of variables are accepted)
  • isNull, isNotNull, isScalarOrNull
  • isResource
  • isNumeric, isInteger, isPositiveInteger, isFloat
  • isScalar
  • isBoolean

There are also some extra methods, which stop the execution in any case: if they are called then it is meant that assertion fails. They are isUnreachable and notImplemented:

try {
	return do_some_stuff();
	
	Assert::isUnreachable();
}
catch (Exception $e) {
	Assert::notImplemented(); // do not forget to implement!
}

Enumerations

While PHP is a loosely-typed language, it does not provide a good base type system, which is presented in other object-oriented languages. In many cases it misses an enumerations, which commonly help to check implicitly whether a passed value is in the set of predefined values.

Phoebius provides an advanced replacement for enumerations with a base Enumeration class.

When you need to define a set of values and gracefuly check whether a coming value is from the predefined set, you just create a descendant of Enumeration and define a desired constants inside it:

Color.class.php

class Color extends Enumeration
{
	const RED = 'color_red';
	const WHITE = 'color_white';
	const BLACK = 'color_black';
}

Then you can refer to it and use it as follows:

function setColor(Color $color)
{
	echo 'Setting a desired color: ', $color->getValue();
}

// prints "Setting a desired color: color_white"
setColor(new Color(Color::WHITE));

To avoid a code mess that makes an instance of enumeration, you can use the following hint making a static method for every commonly-used constant:

class Color extends Enumeration
{
	const RED = 'color_red';
	const WHITE = 'color_white';
	const BLACK = 'color_black';
	
	/**
	 * @return Color
	 */
	static function red()
	{
		return new self (self::RED);
	}
	
	/**
	 * @return Color
	 */
	static function white()
	{
		return new self (self::WHITE);
	}
	
	/**
	 * @return Color
	 */
	static function black()
	{
		return new self (self::BLACK);
	}
}

// usage:
$color = Color::black();

Enumerations is an extremely used feature inside Phoebius to provide extra type checks here and there (see the inheritance diagram).