Structuring Decorators in PHP - php

I'm sort of a novice developer trying to expand my toolbox and learn some more tricks. I recently came across a pattern in Python called "decoration" and I was wondering if/how I could implement this in PHP as I have an existing PHP code base.
Here is a short example of what I mean:
import time
def log_calls(func):
def wrapper(*args, **kwargs):
now = time.time()
print("Calling {0} with {1} and {2}".format(
func.__name__,
args,
kwargs
))
return_value = func(*args, **kwargs)
print("Executed {0} in {1}ms".format(
func.__name__,
time.time() - now
))
return return_value
return wrapper
#log_calls
def test1(a,b,c):
print("\ttest1 called")
#log_calls
def test2(a,b):
print("\ttest2 called")
#log_calls
def test3(a,b):
print("\ttest3 called")
time.sleep(1)
test1(1,2,3)
test2(4,b=5)
test3(6,7)
It doesn't necessarily have to be that syntactically pretty; I understand that all languages have their nuances and I know PHP does not support that syntax. But I still want to be able to achieve the same effect while rewriting as little code as possible.

Basically no, it's not supported in PHP in any way at all. As far as I know, it's not even on the roadmap for future PHP versions.
Of interest, and slightly relevant: The closest I could think of in PHP-land to what you're after is if you use phpUnit to test your code. phpUnit implements something along these lines for its own use, using references in docblock type comments above a method. eg:
/**
* #dataProvider myProviderFunc
*/
public function myTestFunc($argsFromProvider) {
....
}
public function myProviderFunc() {
return array(....);
}
Thus, when phpUnit wants to call myTestFunc(), it first calls myProviderFunc(), and passes the output of that function into myTestFunc().
This strikes me as being close to, but not quite the same as the decorator syntax you're describing. However, it's not standard PHP syntax; phpUnit implements all of this stuff itself. It reads the source code and does a load of pre-processing on as it parses the comment blocks before running the tests, so it's not exactly efficient. Suitable for a unit testing tool, but not for a production system.
But no, the short answer to your question is that what you want can't be done in PHP. Sorry.

PHP has no syntactic support for the decorator pattern, but nothing really hinders you from implementing it yourself.
You can look into the following discussions, which might be relevant to your question:
how to implement a decorator in PHP?
Trying to implement (understand) the Decorator pattern in php
Here is another resource, with UML diagrams and code samples in multiple languages, including PHP.
Decorator Design Pattern

Related

How to document PHPUnit tests

I'm writing a lot of unit tests and I'm afraid one day I'll come back to read the test codes and not be able to understand what's being tested.
The question is: How do i document PHPUnit tests using PHPDoc?
Use the #covers annotation (it's specific to PHPUnit, not a documentation tag used by phpDocumentor) to highlight what the test case is supposed to exercise. By having it in the docblock, you tell the code reader what code is targeted by the test. If you have phpDocumentor also generating docs for your test cases, then it should treat the annotation as a "custom tag", and show it as generic information. Note, though, that the point of #covers is to limit the code coverage measurements done by PHPUnit. Its use as doc info is incidental, but useful.
If you want some kind of document linking between the test case and the tested code, also put the #uses tag in the test case's docblock. That should result in #used-by tag automatically appearing in the documentation for the tested method/function.
One way as suggested is to use the test function name but this can end up too abbreviated and cryptic. In this case put some text in the optional $message parameter to explain what the test is doing.
assertSame(mixed $expected, mixed $actual[, string $message = ''])
I finds this helps, particularly if you are used to writing JavaScript tests with something like Jasmine where you put a human readable sentence to explain what is being tested for each test.
Here is a simple example. If you put the test description as the default value for a function argument it will be documented. If you put just one test per function (i.e. single responsibility principle) then when you look back in a few years time maybe the tests will make more sense than having multiple tests per function.
<?php
use PHPUnit\Framework\TestCase;
final class ArrayPushTest extends TestCase
{
public function testPushStringToEmptyArray(string $description =
'A string is pushed into an empty array at array index 0.'
) : void
{
$a = [];
array_push($a, 'zero');
$this->assertSame('zero', $a[0], $description);
}
}
And this is what it looks like in the docs with phpDocumentor:
phpDocumentor output

All strings and Array as an Object PHP

I want to use all strings and array as an object where we can add our functions.
<?php
// Str class
class Str {
private $str;
public function __construct($str) {
$this->str = $str;
}
public function len() {
return strlen($this->str);
}
public function md5() {
return new static(md5($this->str));
}
public function __toString() {
return $this->str;
}
}
// to cast string into str object
function str($str) {
return new Str($str);
}
// casting string to str object
$str = str("Hello World");
echo $str;
// output: Hello World
echo $str->len();
// output: 11
echo $str->md5()->md5();
// output double md5 of string 'Hello World'
I want to know if it is a good idea to implement this in my high end application. I will add all string functions with my own custom functions to this Str class.
Will it consume too much memory?
Will I encounter any performance issues?
Interesting idea. Resembles JavaScript's String function/object/constructor due to the prototype methods. I've done similar stuff in the past and it didn't have any memory or performance issues. You might want to take advantage of magic methods such as __toString() (which I see you're already doing), as well as __call() and __callStatic(). Also a good idea to add implements Serializable. With some cleverness, you can have a pretty functional class. Although I'd sooner use a string literal since such an implementation wouldn't really offer anything functionality-wise. But if you can think-up a useful implementation, perhaps to build some sort of JavaScript engine, you can start with a top-most class maybe JSObject, then rename your class to maybe JSString and extend it, and also have JSArray and JSDate etc. I'd be interested if you can implement a JavaScript-like environment, with inheritance and all, in PHP. Sounds like a fun side-project to work on, but I can't really think of a practical usage for it. But in terms of expanding your PHP knowledge, and mastering it, I think it's a good learning opportunity to see for yourself PHP's limitations. Push PHP's limitations to the limit and you might learn something. If you decide to go this route, there's 2 more magic methods you can have a load of fun with. __get() and __set(). This way you can just call, for example, $myString->length or $myObject->key="value" and have it stored into an internal array allowing you to easily preform manipulations on the data whenever it changes etc. Just make sure to define a __isset() method if you decide to define dynamic properties. See also: http://php.net/manual/en/reserved.interfaces.php
Edit:
Perhaps a useful implementation would be the ability to define a hierarchy structure such as how many sites have to manage categories/subcategories and the number of products in each category. Such an implementation would allow you to easily define such a hierarchy structure without having to worry about children or number of children or grandchildren etc. But even still, not so practical since I'd sooner just use recursive function to walk such a hierarchy structure. Perhaps a more practical implementation would be an HTML parser of some sort. But this is re-inventing the wheel, although good practice. What I do know, though, is that many PHP frameworks out there take advantage of the above-mentioned features to implement MVC environments. So if you think you can build a better framework than ones already existing, or some other related environment aimed at coders, perhaps that would be the most practical implementation of the above mentioned features.
No,it will not consume too much memory.Also,you don't get any performance issues instead of its reusable across your application.

Creating custom PHP Syntax Parser

I am thinking about how one would go about creating a PHP equivalent for a couple of libraries I found for CSS and JS.
One is Less CSS which is a dynamic stylesheet language. The basic idea behind Less CSS is that it allows you to create more dynamic CSS rules containing entities that "regular" CSS does not support such as mixins, functions etc and then the final Less CSS compiles those syntax into regular CSS.
Another interesting JS library which behaves in a (kind of) similar pattern is CoffeeScript where you can write "tidier & simpler" code which then gets compiled into regular Javascript.
How would one go about creating a simple similar interface for PHP? Just as a proof of concept; I am only trying to learn stuff. Lets just take a simple use case of extending classes.
class a
{
function a_test()
{
echo "This is test in a ";
}
}
class b extends a
{
function b_test()
{
parent::a_test();
echo "This is test in b";
}
}
$b = new b();
$b->b_test();
Suppose I want to let the user write class b as (just for the example):
class b[a] //would mean b extends a
{
function b_test()
{
[a_test] //would mean parent::a_test()
echo "This is test in b";
}
}
And let them later have that code "resolve" to regular PHP (Usually by running a separate command/process I would believe). My question is how would I go about creating something like this. Can it be done in PHP, would I require to use something like C/C++. How should I approach this problem if I were to go at it? Are there any resources online? Any pointers are deeply appreciated!
Language transcoders are not as easy as one might think.
The example you gave can be implemented very easily with a preg_replace that looks for class definitions and replaces [a] with extends a.
But more complex features need a transcoder which is a suite of smaller logical pieces of code.
In most programmer jargon people incorrectly call transcoders compilers but the difference between compilers and transcoders is that compilers read source code and output raw binary machine code while transcoders read source code and output (a different) source code.
The PHP (or JavaScript) runtime for example is neither compiler nor transcoder, it's an interpreter.
But enough about jargon let's talk about transcoders:
To build a transcoder you must first build a tokenizer, it breaks apart the source code into tokens, meaning that if it sees an entire word such as 'class' or the name of a class or 'function' or the name of a function, it captures that word and considers it a token. When it encounters another token such as an opening round bracket or an opening brace or a square bracket etc. it considers that another token.
Luckily all of the recognized tokens available in PHP are already easily scanned by token_get_all which is a function PHP is bundled with. You may have some trouble because PHP assumes some things about how you use symbols but all in all you can make use of this function.
The tokenizer creates a flat list of all the tokens it finds and gives it to the parser.
The parser is the second phase of your transcoder, it reads the list of tokens and decides stuff like "if token[0] is a class and token[1] is a name_value then we have a class" etc.. after running through the entire list of tokens we should have an abstract syntax tree.
The abstract syntax tree is a structure that symbolically retains only the relevant information about a the source code.
$ast = array(
'my_derived_class' => array(
'implements' => array(
'my_interface_1',
'my_interface_2',
'my_interface_3'),
'extends' => 'my_base_class',
'members' => array(
'my_property_name' => 'my_default_value',
'my_method_name' => array( /* ... */ )
)
)
);
After you get an abstract syntax tree you need to walk through it and output the destination source code.
The real tricky part is the parser which (depending on the complexity of the language you are parsing) may need a backtracking algorithm or some other form of pattern matching to differentiate similar cases against one another.
I recommend reading about this in Terence Parr' book http://pragprog.com/book/tpdsl/language-implementation-patterns which describes in detail the design patterns needed to write a transcoder.
In Terrence' book you'll find out why some languages such as HTML or CSS are much simpler (structurally) than PHP or JavaScript and how that relates the complexity of the language parser.

What code is this?

Please consider the following code snippet:
From php-5.3.1/ext/session/session.c:
PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS)
…
gettimeofday(&tv, NULL);
…
/* maximum 15+19+19+10 bytes */
spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ?
remote_addr : "", tv.tv_sec, (long int)tv.tv_usec,
php_combined_lcg(TSRMLS_C) * 10);
…
return buf;
}
I have found it on the internet. But I can't understand what code is this. I guess this is the implementation of a php function in C++. If yes, then please explain me how php calles c++ function in it?
The shocking truth is that PHP is written in C. You are looking at the source of PHP itself, or need to explain the question further.
It is not a C++ code, it is pure C. The PHP library can call C functions just like any other library implemented in C. The code snippet generates a "unique" session ID consisting of the client address, the current time, and a pseudo-random number from some linear congruential generator.
I am guessing that you ended up to that piece of code via the DEFCON 18: How I Met Your Girlfriend lecture? Great talk btw. :-)
Now about the code snippet, it is C and it is part of PHP's code. This exact function handles the generation of PHP session ids. You have the entire function logic explained in the lecture i mentioned above, in case you didn't see it.
As a side not, PHP does not call C functions, instead you call a PHP library function and so it happens that most of those functions are written in C and exposed through PHP. On the other hand php_session_create_id does not have an equivalent exposed to PHP, since that one is used internally by PHP when you start a session using PHP session api.

What are some useful PHP Idioms?

I'm looking to improve my PHP coding and am wondering what PHP-specific techniques other programmers use to improve productivity or workaround PHP limitations.
Some examples:
Class naming convention to handle namespaces: Part1_Part2_ClassName maps to file Part1/Part2/ClassName.php
if ( count($arrayName) ) // handles $arrayName being unset or empty
Variable function names, e.g. $func = 'foo'; $func($bar); // calls foo($bar);
Ultimately, you'll get the most out of PHP first by learning generally good programming practices, before focusing on anything PHP-specific. Having said that...
Apply liberally for fun and profit:
Iterators in foreach loops. There's almost never a wrong time.
Design around class autoloading. Use spl_autoload_register(), not __autoload(). For bonus points, have it scan a directory tree recursively, then feel free to reorganize your classes into a more logical directory structure.
Typehint everywhere. Use assertions for scalars.
function f(SomeClass $x, array $y, $z) {
assert(is_bool($z))
}
Output something other than HTML.
header('Content-type: text/xml'); // or text/css, application/pdf, or...
Learn to use exceptions. Write an error handler that converts errors into exceptions.
Replace your define() global constants with class constants.
Replace your Unix timestamps with a proper Date class.
In long functions, unset() variables when you're done with them.
Use with guilty pleasure:
Loop over an object's data members like an array. Feel guilty that they aren't declared private. This isn't some heathen language like Python or Lisp.
Use output buffers for assembling long strings.
ob_start();
echo "whatever\n";
debug_print_backtrace();
$s = ob_get_clean();
Avoid unless absolutely necessary, and probably not even then, unless you really hate maintenance programmers, and yourself:
Magic methods (__get, __set, __call)
extract()
Structured arrays -- use an object
My experience with PHP has taught me a few things. To name a few:
Always output errors. These are the first two lines of my typical project (in development mode):
ini_set('display_errors', '1');
error_reporting(E_ALL);
Never use automagic. Stuff like autoLoad may bite you in the future.
Always require dependent classes using require_once. That way you can be sure you'll have your dependencies straight.
Use if(isset($array[$key])) instead of if($array[$key]). The second will raise a warning if the key isn't defined.
When defining variables (even with for cycles) give them verbose names ($listIndex instead of $j)
Comment, comment, comment. If a particular snippet of code doesn't seem obvious, leave a comment. Later on you might need to review it and might not remember what it's purpose is.
Other than that, class, function and variable naming conventions are up to you and your team. Lately I've been using Zend Framework's naming conventions because they feel right to me.
Also, and when in development mode, I set an error handler that will output an error page at the slightest error (even warnings), giving me the full backtrace.
Fortunately, namespaces are in 5.3 and 6. I would highly recommend against using the Path_To_ClassName idiom. It makes messy code, and you can never change your library structure... ever.
The SPL's autoload is great. If you're organized, it can save you the typical 20-line block of includes and requires at the top of every file. You can also change things around in your code library, and as long as PHP can include from those directories, nothing breaks.
Make liberal use of === over ==. For instance:
if (array_search('needle',$array) == false) {
// it's not there, i think...
}
will give a false negative if 'needle' is at key zero. Instead:
if (array_search('needle',$array) === false) {
// it's not there!
}
will always be accurate.
See this question: Hidden Features of PHP. It has a lot of really useful PHP tips, the best of which have bubbled up to the top of the list.
There are a few things I do in PHP that tend to be PHP-specific.
Assemble strings with an array.
A lot of string manipulation is expensive in PHP, so I tend to write algorithms that reduce the discrete number of string manipulations I do. The classic example is building a string with a loop. Start with an array(), instead, and do array concatenation in the loop. Then implode() it at the end. (This also neatly solves the trailing-comma problem.)
Array constants are nifty for implementing named parameters to functions.
Enable NOTICE, and if you realy want to STRICT error reporting. It prevents a lot of errors and code smell: ini_set('display_errors', 1); error_reporting(E_ALL && $_STRICT);
Stay away from global variables
Keep as many functions as possible short. It reads easier, and is easy to maintain. Some people say that you should be able to see the whole function on your screen, or, at least, that the beginning and end curly brackets of loops and structures in the function should both be on your screen
Don't trust user input!
I've been developing with PHP (and MySQL) for the last 5 years. Most recently I started using a framework (Zend) with a solid javascript library (Dojo) and it's changed the way I work forever (in a good way, I think).
The thing that made me think of this was your first bullet: Zend framework does exactly this as it's standard way of accessing 'controllers' and 'actions'.
In terms of encapsulating and abstracting issues with different databases, Zend_Db this very well. Dojo does an excellent job of ironing out javascript inconsistencies between different browsers.
Overall, it's worth getting into good OOP techniques and using (and READING ABOUT!) frameworks has been a very hands-on way of getting to understand OOP issues.
For some standalone tools worth using, see also:
Smarty (template engine)
ADODB (database access abstraction)
Declare variables before using them!
Get to know the different types and the === operator, it's essential for some functions like strpos() and you'll start to use return false yourself.

Categories