Skip to content

zend framework 2 (zf2) - where to find the default manager config key names

For exampe, you want to add your own controller plugin in the module.config, do you know the key name out of the box? Me neither, but i know where to look.
Open the ModuleManagerFactory and serch for view_helpers to get the spot where and how the configuration array key names are defined.
After this, the adding of your controller plugin is a solveable task :-).

Translate to de es fr it pt ja

PHP Proxy Logger Component - Put Back Some Freedom And Silence In You Logs

So what is this component all about?
Basically it is a self developed "Proxy Logger" for php. Furthermore, this projects extends the proxy logger with an buffer and again with a trigger to flush or clean this buffer.

What does a "Proxy Logger" for php mean? It means a proxy for all loggers which implements the "PSR-3 Logger Interface". The proxy forwards all log requests to all attached loggers.
By using the provided "Buffer Logger", you are able to manipulate the forwarding of the log requests to all attached loggers.
Additionally, you can manipulate the buffering itself by using the available "Buffer Manipulators". This enables the possibility to set a trigger for log level to regulate the forwarding of all log requests to all attached loggers.

By the time of this writing, the component is shipped with two manipulators, the "BypassBuffer" and the "FlushBufferTrigger".
You can use the "Bypass Buffer" to regulate which log level bypasses the buffer and are forwarded directly to all attached loggers. The "Flush Buffer Trigger" enables the way to mark a log level as trigger. If this log level is triggerd, the buffer will be flushed which means that all buffered log requests are forwarded to all attached loggers.

After writing about all the fundamental knowledge, lets move on to the "Upward Flush Buffer". The upward flush buffer extends the idea of a triggerd buffer flush by the concept of triggering this flush also if a log level of a higher priority is called. To keep it short, you can define "if at least this log level is called, flush the buffer".

The whole component is shipped with a log of examples.
Since the upward flush buffer trigger is the crown jewel of the component, i want to quote the output of the upward flush buffer trigger versus normal logger example.


----------------------------------------
First run with normal logger without log level restriction.
----------------------------------------
[1381003509] [debug] [processing id 1]
[1381003509] [info] [collection information and data id: 1]
[1381003509] [debug] [done]
[1381003509] [debug] [processing id 3]
[1381003509] [info] [collection information and data id: 3]
[1381003509] [info] [data can not handled with this process, queueing data to manual processing list]
[1381003509] [debug] [done]
[1381003509] [debug] [processing id 8]
[1381003509] [info] [collection information and data id: 8]
[1381003509] [info] [logical problem in data on key 3]
[1381003509] [notice] [trying to recalculate data]
[1381003509] [info] [setting data value of key 7 to default]
[1381003509] [debug] [finished]
[1381003509] [debug] [processing id 4]
[1381003509] [info] [collection information and data id: 4]
[1381003509] [debug] [done]
[1381003509] [debug] [processing id 5]
[1381003509] [info] [collection information and data id: 5]
[1381003509] [info] [logical problem in data on key 6]
[1381003509] [notice] [trying to recalculate data]
[1381003509] [warning] [setting data value of key 7 to default not possible]
[1381003509] [notice] [trying to revert modification]
[1381003509] [error] [runtime data and data in storage differs, can not revert modification]
[1381003509] [critical] [lost connection to storage]
[1381003509] [alert] [can not unlock and schedule processing to id 5]
[1381003509] [debug] [done]
[1381003509] [debug] [processing id 6]
[1381003509] [critical] [lost connection to storage]
[1381003509] [alert] [can not unlock and schedule processing to id 6]
[1381003509] [debug] [done]
----------------------------------------
Second run with normal logger and log level restriction to warning and above.
----------------------------------------
[1381003509] [warning] [setting data value of key 7 to default not possible]
[1381003509] [error] [runtime data and data in storage differs, can not revert modification]
[1381003509] [critical] [lost connection to storage]
[1381003509] [alert] [can not unlock and schedule processing to id 5]
[1381003509] [critical] [lost connection to storage]
[1381003509] [alert] [can not unlock and schedule processing to id 6]
----------------------------------------
Third run with manipulate buffer logger.
----------------------------------------
[1381003509] [debug] [processing id 5]
[1381003509] [info] [collection information and data id: 5]
[1381003509] [info] [logical problem in data on key 6]
[1381003509] [notice] [trying to recalculate data]
[1381003509] [warning] [setting data value of key 7 to default not possible]
[1381003509] [notice] [trying to revert modification]
[1381003509] [error] [runtime data and data in storage differs, can not revert modification]
[1381003509] [critical] [lost connection to storage]
[1381003509] [alert] [can not unlock and schedule processing to id 5]
[1381003509] [debug] [processing id 6]
[1381003509] [critical] [lost connection to storage]
[1381003509] [alert] [can not unlock and schedule processing to id 6]

What does this example show you?
The example shows typical log entries generated by a process that is dealing with a bunch of data.
"First run" is the regular massiv number of entries you have to deal with when you are running you logger without restrictions.
As you can see, it takes some time to figure out if something important happens. Even to find the place where something important happens is hard to find. The "second run" is an example when you run you logger in the restriction of "only log level of warning or above".
First of all, you notice that no debug or info messages are logged. But what is bad about that? You either miss important informations (like the process or data id) or you have to flood your logs with all informations for each log request.
Finally, the "third run" shows what i mean when i am writing about "putting back freedom and silence in your log files". The logger only logs when a critical log level is reached and provides all available informations. If nothing bad happens, nothing will be logged. Quite nice, isn't it?
If a part of the data is processed, the buffer is cleaned when nothing happens. If an important log level is triggerd, the buffer is flushed and all collected log requests are forwarded to all attached loggers.

If you find bugs, bad namings, ugly code, have ideas to improve this component, pull your code or became a participant :-).

Translate to de es fr it pt ja

tool php classmap generator packagist

After a month, i've finished a tool to create a classmap from a php project. The current stable version is v1.4 and can be found on github.com as well as on packagist.org. Why? Well, obviously because i can (and wanted to learn a few things like tokens, or symfony console) ;-). But for real, when you have to deal with legacy projects or code but want to remove the strange and slow existing autoloader (with all its exception), the easiest way to do this is by using a classmap. I also tried to find a classmap generator that can deal with psr-0 and not psr-0 files, all i could find are generators that support psr-0 files. A classmap itself is just a php array. The key is the full qualified classname and the value is the relative path to the file. Creating a classmap on your own is suitable when you have to manage a number of files below 20. But when it comes to more you can not effort the time to maintain that file. So for a lot of files that are not covert by composer, the classmap generator should be well suitable. It is planned to implement a "phar" classmap generation for the upcoming version. When you want to create phar files, this could be a timesaver as well. The classmap generator is build by using symfony\console and yes, it is a joy to work with that component! Shame on me, the current version is not covered by unittests. After i implemented the current features from the todo list, this will be my major task.

The classmap generator can handle all kind of php files like: - Interface - Abstract Class - Class The generator can handle files with or without namespace. Even files with multiple definitions (interface, abstract class and class in one file) is no problem.

Furthermore, you can create multiple configuration files and update this classmaps when needed. Like well known from the composer, the classmap generator is able to create a autoloader file for you. The created autoloader will use the created classmap file and supports psr-0 autoloading.

source/link to the wiki

What is left to write? Of course i'm proud about this. What you see right now is the work of one month and after i finished the core design, i rebuild a lot by replacing my cli application class with the symfony\console component.

I hope you can use the tool. If you need help or found a bug, contact me on github.com

Translate to de es fr it pt ja

tool - php 5.3 - some new functions

Since php 5.4. throws his shadow i finally had some time to check the release notes of 5.3. Here are some changes that are made in PHP 5.3, i just picked up my favorits (as expected ;-) ).

New Global Constants __DIR__ __NAMESPACE__

New Functions arrayreplace: replaces elements from passed arrays into the first array arrayreplacerecursive: replaces elements from passed arrays into the first array recursively classalias: rreates an alias for a class header_remove: remove previously set headers

I have not used one of this functions but since i am a developer i knew a lot of situations where this functons could have saved time.

other changes to extensions cURL: cURL now supports SSH OpenSSL: OpenSSL digest and cipher functions are now supported. Session: Sessions will no longer store session-files in "/tmp" when open_basedir restrictions apply, unless "/tmp" is explicitly added to the list of allowed paths.

new methods DateTime::add(): Adds an amount of days, months, years, hours, minutes and seconds to a DateTime object DateTime::diff(): Returns the difference between two DateTime objects. DateTime::sub(): Subtracts an amount of days, months, years, hours, minutes and seconds from a DateTime object.

Translate to de es fr it pt ja

callbacks, anonymous or lambda functions - the differences

It just took me a while to really understand the differences between this three. But hopefully (never say never ;-), now i got it. A callback simple describes, that a function awaits another function as parameter. This functions can be an existing one or a "on the fly created on" with the power of create_function.

A lambda function is a function without a function name. The reference is stored in a variable. You can use this variable to handle it over to methods like usort. As everybody i will use a sorting lambda function for showing what i mean.

$lengthOfStringTwo) { $sorter = 1; } elseif ($lengthOfStringOne < $lengthOfStringTwo) { $sorter = -1; } return $sorter; }; $names = array( 'Brian W. Kernighan', 'Dennis Ritchie' ); usort($names, $mySorter); echo xdebug_var_dump($names); ?>

It is also possible to define the $mySorter directly in unsort as second parameter like

usort($names, function($stringOne, $stringTwo { ... });
if you like that.

A closure is a function that surrounds (i do not want to use the word enclose ;-)) the lambda function.

That has the sideeffect that the closure itself conserves their own context. An easy example is a simple logger.

setMessage($message); $myDatabaseInfoLogTable->setTimestamp(mktime()); $status = $myDatabaseInfoLogTable->save(); break; case 'error': $myFileErrorLog = new ErrorLog(); $myFileErrorLog->addMessage(mktime() . "\t" . $message); $status = $myFileErrorLog->save(); break; } return $status; }; } $infoLogger = myClosureLogger('info'); $errorLogger = myClosureLogger('error'); $infoLogger('This is a info log'); $errorLogger('This is an error log'); ?>

The positiv thing about closures is, that the code footprint can be reduced (you even can use closures inside objects - even as static if you do not need to access on the object itself with $this). The negativ thing is, that you can not use interfaces which implies a lose of security.

Translate to de es fr it pt ja