PHP7 was released on the 3rd of December, 2015. This new version brought forward a large number of new and exiting features (https://php.net/manual/en/migration70.new-features.php) to PHP. Perhaps one of the biggest of the new features is a new Zend Engine (the engine that powers PHP).
This new engine, code named PHPNG, will give some of your applications double the performance speed.
Some benchmarks that have been run so far:
It is only natural that once it came out the PhalconPHP community was dying to know when we would get a chance to work with PhalconPHP and PHP7.
We all know that PhalconPHP is written in Zephir starting with version 2.0, and that this language compiles its code into a C PHP Extension. Because of PHP7’s new engine the extension had to be rewritten and adapted to the new specifications.
Knowing this, the PhalconPHP team started working since last year on an updated version of Zephir to make the compiled code work with PHP7.
After a few months we are finally delivered PhalconPHP 2.1 and Zephir 0.9.x which brings PHP7 support.
You will need to install PHP7+ and Zephir 0.9.2a-dev (or its latest branch). After you have them installed go to PhalconPHP 2.1.0+ branch and download the source code.
Installation example:
root@localhost:~$ cd cphalcon-2.1.x/
root@localhost:~/cphalcon-2.1.x$ zephir build —backend=ZendEngine3
If you get these warnings ignore them:
Warning: Variable "_SESSION" assigned but not used in Phalcon\Session\Adapter::remove in /root/cphalcon-2.1.x/phalcon/session/adapter.zep on 204 [unused-variable]
}
-^
Warning: Variable "beforeLine" assigned but not used in Phalcon\Debug::showTraceItem in /root/cphalcon-2.1.x/phalcon/debug.zep on 339 [unused-variable]
beforeLine, firstLine, afterLine, lastLine, i, linePosition, currentLine;
-------------^
Warning: Variable "possibleSetter" declared but not used in Phalcon\Mvc\Model::assign in /root/cphalcon-2.1.x/phalcon/mvc/model.zep on 440 [unused-variable]
var key, keyMapped, value, attribute, attributeField, possibleSetter, metaData, columnMap, dataMapped;
----------------------------------------------------------------------^
Warning: Function "\\sodium\\randombytes_buf" does not exist at compile time in /root/cphalcon-2.1.x/phalcon/security/random.zep on 119 [nonexistent-function]
return \\Sodium\\randombytes_buf(len);
----------------------------------------^
Warning: Function "\\sodium\\randombytes_uniform" does not exist at compile time in /root/cphalcon-2.1.x/phalcon/security/random.zep on 310 [nonexistent-function]
return \\Sodium\\randombytes_uniform(len);
--------------------------------------------^
Compiling...
Installing...
Extension installed!
Don't forget to restart your web server
root@localhost:~/cphalcon-2.1.x$ service php-fpm restart
That’s it!
You now have PhalconPHP and PHP7 working.
Can you expect PhalconPHP to be even faster? No, but you can expect to see your your app be much faster since your PHP code will run better with the new engine. Plus, you won’t have any overhead since PhalconPHP is a extension. The best part of all this is that you get all the new features that PHP7 brings to the table.
Do take into account that PHP7 is still rather new, and most of the commonly used extensions like memcache, memcached, and redis are available in Dev/Beta branches, so you need to reinstall them.
Best of luck to all and enjoy PhalconPHP + PHP7.
We are excited to announce the immediate availability of Phalcon 2.0.10!
This is the tenth maintenance release in the 2.0.x series, adding more fixes and improvements to make the most of Phalcon.
We are excited to announce the immediate availability of Phalcon 2.0.9!
This is the ninth maintenance release in the 2.0.x series, adding more fixes and improvements to make the most of Phalcon.
We are excited to announce the immediate availability of Phalcon 2.0.8 and Phalcon 2.1.0 beta 2!
This is the eighth maintenance release in the 2.0.x series. In regards to Phalcon 2.1, the second beta introduces bug fixes and new features intended to stabilize our next major release.
Phalcon is a framework that differs from the rest. We can’t update the source code from composer like other frameworks, we have to recompile the extension with each new update. Some can find this as a problem. Others, like us, find it entertaining.
Phalcon recently launched its new version (2.0). With this new version we’ve seen a large number of improvements, but as with every software we’ve also got some new bugs. However some of us can’t wait for the new release to get the bug fix, we need the latest and greatest version. This is where we need to either compile Phalcon from Zephir or download the latest build.
To get the latest version of Phalcon go to PhalconPHP’s GIT and get the version of the branch you are using. (For this article let got with 2.1.x.)
[https://github.com/phalcon/cphalcon/tree/2.1.x][https://web.archive.org/web/20160322143039/https://github.com/phalcon/cphalcon/tree/2.1.x]
Now you have 2 options, the build way or the recompile way. On this article we will focus on the build way.
Download the latest version either via GIT or direct download
[root@server ~] wget https://github.com/phalcon/cphalcon/archive/2.1.x.zip
[root@server ~] unzip 2.1.x.zip
[root@server ~] cd cphalcon-2.1.x/
List everything on the folder
[root@server cphalcon-2.1.x] ls
build CHANGELOG.md codeception.yml codecept.phar composer.json config.json CONTRIBUTING.md docs ext optimizers phalcon php-tests README.md run-tests.sh tests unit-tests
We can see 2 folders: build and ext. If we are installing the latest stable version we normally go with the folder build; but since we are going to install the latest unstable version we need to got to the folder ext
[root@server cphalcon-2.1.x] cd ext
Now we need to compile the new version. Simply run the install command
[root@server cphalcon-2.1.x] ./install
That’s it, restart PHP-FPM or Apache. Welcome to the edge of Phalcon. ;)
[root@server ext] /etc/init.d/php-fpm restart
Enjoy. If you find bugs please report them on github.
We’re excited to announce the first beta release of Phalcon 2.1!
The 2.1.x series are going to be supported for a much longer period than previous versions, thus it is marked as our first Long Term Support LTS release!
In the Phalcon 2.”0.x” series, we introduced a lot of new features as well as bug fixes. Our focus however has always been to keep backwards compatibility with Phalcon 1.3.x series, while at the same time encourage developers to upgrade to 2.0.x. This allowed ample time for developers to adjust their applications to work with the 2.0.x series.
After doing some searching around the PhalconPHP documentation, forums, and Google it became apparent that one of two things were happening here: either no one that is using PhalconPHP has had to do rerouting or there is a way and it just hasn’t been shared with the rest.
Either way, after digging through the PhalconPHP API we found something that could help us with what we wanted. Therefore we created a solution to what we needed. It might not be the prettiest or best one out there, but it worked and took care of it.
The issue:
While performing SEO optimization to a site that had already been online for some time, and that had already been indexed by Google it came to our attention of URLs that were 4 and 5 levels deep. According to SEO, URLs should try to stick to being 3 levels deep, 4 at most if it cannot be avoided.
Examples of URL depths:
http://domain.com/level2/level4/level5/level6/…
Correct way:
http://domain.com/level2/level3-level4-level5-level6-…
Our solution:
Take this original route definition (ignore how unusual it maybe, it is for example’s sake):
$router->add('/level2/level3/([0-9]+)/([0-9]+)', [
'namespace' => 'Project\\Controllers\\',
'controller' => 'index',
'action' => 'getLevel',
'param1' => 'level3',
'param2' => 1,
'param3' => 2,
]);
We wanted to perform a 301 redirect on that URL in order to allow the new URL format without losing what had already been indexed.
We know $router is an instance of Phalcon\Mvc\Router, and when we add a route using $route->add() we get back an instance of Phalcon\Mvc\Router\Route. With that in mind we went to explore the API and found something within the Route class: beforeMatch().
A thought went across our heads, so we decided to test it.
$router->add('/level2/level3/([0-9]+)/([0-9]+)', [
'namespace' => 'Project\\Controllers\\',
'controller' => 'index',
'action' => 'getLevel',
'param1' => 'level3',
'param2' => 1,
'param3' => 2,
])->beforeMatch(function(){
die(‘Testing beforeMatch');
})
Don’t judge. We know you use die() too. And it effectively printed the string when the URL was invoked. Neat! Well, the API doesn’t not specify any parameters, but surely there must be some, right? After all it is a callback, which means something should be sent back to us. Well, by specifying parameters we confirmed that 3 pieces of information are being sent back to the callback function:
Param 1: The match URL string.
Param 2: A Phalcon\Mvc\Router\Route object.
Param 3: A Phalcon\Mvc\Router object.
In the end we only needed the first two parameters in order to do what was needed.
$router->add('/level2/level3/([0-9]+)/([0-9]+)', [
'namespace' => 'Project\\Controllers\\',
'controller' => 'index',
'action' => 'getLevel',
'param1' => 'level3',
'param2' => 1,
'param3' => 2,
])->beforeMatch(function($matchedRoute, $routeObject){
// do something
});
Furthermore, it came to our attention that we did not need to specify the route’s paths:
$router
->add('/level2/level3/([0-9]+)/([0-9]+)')
->beforeMatch(
function ($matchedRoute, $routeObject) {
// do something
}
)
;
Now all we had to do was work with this to get the redirect going. Through Phalcon\Mvc\Router\Route we found getCompiledPattern(). This will return the complete regular expression for the defined pattern.
$router
->add('/level2/level3/([0-9]+)/([0-9]+)')
->beforeMatch(
function ($matchedRoute, $routeObject) {
preg_match(
$routeObject->getCompiledPattern(),
$matchedRoute,
$params
);
}
)
;
Good so far. Next we defined the URL to where we wanted to do the redirection:
$router
->add('/level2/level3/([0-9]+)/([0-9]+)')
->beforeMatch(
function ($matchedRoute, $routeObject) {
preg_match(
$routeObject->getCompiledPattern(),
$matchedRoute,
$params
);
$url = '/level2/level3-' . $params[1] . '-' . $params[2];
}
)
;
The last thing we needed was to do the redirection. None of the parameters supplied by PhalconPHP could help us on that, so we decided to invoke our good old friend, the Dependency Injector (DI):
$router
->add('/level2/level3/([0-9]+)/([0-9]+)')
->beforeMatch(
function ($matchedRoute, $routeObject) {
preg_match(
$routeObject->getCompiledPattern(),
$matchedRoute,
$params
);
$url = '/level2/level3-' . $params[1] . '-' . $params[2];
return \Phalcon\DI::getDefault()
->getResponse()
->redirect($url, true, 301);
}
)
;
And there you have it. A 301 redirect in PhalconPHP directly from the routes. Call it rerouting if you want.
We are excited to announce the release of Phalcon 2.0.7! This is our seventh release in the 2.0.x series and it contains bug fixes and new features for your enjoyment!
PHP is a single inheritance language. This limitation created challenging situations for a lot of PHP developers. Thankfully this limitation was solved in PHP 5.4 with the introduction of traits.
Here is a brief overview on traits.
Traits are a very handy way of reusing code in PHP. This allowed to overcome the single inheritance limitation that PHP had. It enabled developer to reuse methods across several independent classes residing in different class arrangements. Traits reduce complexity, and allows to helps prevent problems that were associated to multiple inheritance and mixins.
Traits are very similar to classes, but are intended to group up functionality in a smooth and uniform way, and they cannot be instantiated on their own. It is an expansion to traditional inheritance and enables a horizontal scaling behavior; as in, utilization of class members without having to require inheritance.
Now, onto what you came here for.
I like to think that I am organized. I’ve been told so, but I think that there is always room for improvement. Therefore when adding traits to a project I like to create a
traitsdirectory under myappdirectory. Placement is not really that important, but I like to keep it clean (for example you could create the traits folder under your library folder). Here is how to looks:
The next step after creating the folder is integrating it into our working environment. Open the /app/config/config.php file and add a reference to the directory under application.
return new \Phalcon\Config([
'siteName' => getenv('SITE_NAME'),
'siteUrl' => 'http://'.getenv('SITE_NAME'),
'controllersDir' => getenv('BASE_DIR') . 'app/controllers/',
'modelsDir' => getenv('BASE_DIR') . 'app/models/',
'viewsDir' => getenv('BASE_DIR') . 'app/views/',
'pluginsDir' => getenv('BASE_DIR') . 'app/plugins/',
'libraryDir' => getenv('BASE_DIR') . 'app/library/',
'cacheDir' => getenv('BASE_DIR') . 'app/cache/',
'traitsDir' => getenv('BASE_DIR') . 'app/traits/'
'baseDir' => getenv('BASE_DIR'),
'baseUri' => '/'
]
]);
Next, open the /app/config/loader.php file and add register the namespace reference.
$loader->registerNamespaces(array(
'Project\Controllers' => $config->application->controllersDir,
'Project\Traits' => $config->application->traitsDir
));
$loader->register();
That’s it! Well, aside from actually creating a trait and applying for use. Take this trait for example:
namespace Project\Traits;
trait HttpBehavior
{
/**
* Set JSON response for AJAX, API request
*
* @param string $content
* @param integer $statusCode
* @param string $statusMessage
*
* @return \Phalcon\Http\Response
*/
public function jsonResponse($content, $statusCode = 200, $statusMessage = 'OK')
{
// Encode content
$content = json_encode($content);
// Create a response since it's an ajax
$response = new \Phalcon\Http\Response();
$response->setStatusCode($statusCode, $statusMessage);
$response->setContentType('application/json', 'UTF-8');
$response->setContent($content);
return $response;
}
}
Now, to use it just go where you want to include it and invoke it:
namespace Project\Controllers;
class IndexController extends ControllerBase
{
/**
* Invoke Traits
*/
use \Project\Traits\HttpBehavior;
/**
* Does something...
*
* @param $someVar
*
* @return \Phalcon\Http\Response
*/
public function doSomethingAction($someVar = '')
{
// Do this and that and get something to return
$content = [
'id' => 1,
'message' => 'something'
];
// Return response
return $this->jsonResponse($content);
}
}
Very simple and elegant.