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.
Related
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
Target is to have something like:
#define sum( f1, f2 ) ( f1 + f2 )
where
sum(2,2)
is 4 in PHP. Is that somehow possible? Even better would be if I could call:
$s = 'first';
APPEND ' and second';
when append will be defined as function/method/something else which is appending to $s so after those 2 lines $s would be 'first and second'.
The point of macros in C is that they are expanded at compile time.
Therefore, using the macros does not have an impact on the speed of your code, which a function doing the same would have.
Therefore, an example of usage is:
#define MYPRINTF(x) printf("MYPRINTF says : %s\n",x)
MYPRINTF("blah");
The code above will be translated by the compiler directly into:
printf("MYPRINTF says : %s\n","blah");
The whole point of it is that it is faster than defining a function, such as this one:
void myprintf(char *x)
{
printf("myprintf says : %s\n","blah");
}
Because there is no overhead (in a function, you need to push arguments to the stack, etc).
In an interpreted language, like PHP, the above doesn't hold, as everything is executed directly during run-time, therefore using a mechanism like C's #define would be absolutely useless -- therefore, to answer your question, simply use ordinary functions instead.
just a thought from your comments
function withVeryLongWroteByAnIdiot() {
....
}
function xFunc() {
return withVeryLongWroteByAnIdiot();
}
PHP doesn't support macros in this sense, the (really quite valid) argument I believe being that there's not much difference between this and a normal function in PHP.
After all, it's not like there's any value in having a concept like this in a run-time interpreted language.
I don't believe PHP supports macros. If you think about it, macros in C aren't fancy constants, rather constants are the world's most boring C macros. PHP only understands the boring form through the define function.
That said, I disagree with the other respondents about their validity. There is a valid reason for them: when you want to use built-in functions to preprocess something. For example:
macro default_if_empty_value(value, default) (empty(value) ? default : value)
If you try to write that as a function and call it:
default_if_empty_value($this->that['something']->or[$other], 'Not here.');
then you'll get a PHP warning if any part of that variable chain is not defined, and the expanded version is harder to read:
empty($this->that['something']->or[$other]) ? 'Not here.' : $this->that['something']->or[$other];
PHP code is compiled, but it is compiled at runtime. A macro like this would be expanded by the PHP interpreter and then compiled into PHP bytecode. This bytecode is often cached by the PHP interpreter or an add-on like APC.
I am using SWIG to generate a PHP extension that calls into a 'c' shared lib. I am able to get most things to work except the following situation...
In my 'c' code I declare a function as (Please note that structure and function names have been changed to protect the innocent):
int getAllThePortInfo(EthernetPort *ports);
In this case, the parameter ports is actually an array of EthernetPort structures. In another 'c' program, I could have called it like this...
EthernetPort ports[4];
int rval = getAllThePortInfo(ports);
<etc>
<etc>
This works fine. Then I run SWIG, generate my shared lib, and all builds well. I get php code that I can call...
$ports = new_ethernetport();
$rval = getAllThePortInfo($ports);
This causes PHP to throw the following error : php: free(): invalid pointer: 0x099cb610
So, I tried to do something like...
$ports = array(new_ethernetport(), new_ethernetport(), new_ethernetport(), new_ethernetport());
$rval = getAllThePortInfo($ports);
But then PHP complained...
PHP Fatal error: Type error in argument 1 of getAllThePortInfo. Expected SWIGTYPE_p_EthernetPort
What I think is happening is that PHP (and SWIG) do not differentiate between pointers and arrays, and in the wrapper, it is thinking 'pointer to a single structure', when, in reality, it is an array of structures.
Is there something in PHP I can do? Allocate a chunk of memory that I can use as a space to store more than one structure?
Is there something with SWIG I can do to make my wrapper understand my intentions better?
I truly would appreciate any suggestions. Thanks.
carrays.i indeed hold the answer to my question...
In the SWIG interface file, I have the following lines...
%include <carrays.i>
%array_functions(EthernetPort, ethernetPortArray);
%include "my_lib.h"
"my_lib.h" contains the typedef for the EthernetPort structure, as well as the function declaration...
#define NUM_ETHERNET_PORTS 4
typedef struct {
int number;
mode_t mode;
} EthernetPort;
int getAllThePortInfo(EthernetPort *ports);
After running SWIG and building the shared lib my_lib.so, I can use the following PHP code...
$ports = new_ethernetPortArray(NUM_ETHERNET_PORTS);
$rval = getAllThePortInfo($ports);
$port0 = ethernetPortArray_getitem($ports, 0);
$pnum = ethernetport_number_get($port1);
$pmode = ethernetport_mode_get($port1);
// port1 port2 port3 etc etc
delete_ethernetPortArray($ports);
The php functions new_ethernetPortArray, ethernetPortArray_getitem, ethernetport_number_get, ethernetport_mode_get, delete_ethernetPortArray were all created by SWIG based on the .i file.
The other benefit SWIG enables is the use of #define's in my php code (e.g. NUM_ETHERNET_PORTS), allowing me a single place for some of my common data. I like that. :-)
Cheers.
#DoranKatt, your solution worked for me too with one minor tweak. I had to change the order in the swig file:
%include <carrays.i>
%include "my_lib.h"
%array_functions(EthernetPort, ethernetPortArray);
with the original order I found it generated code that did not compile because the array functions referred to a type that was included later in "my_lib.h". Of course my code used different names and types but I've kept the original authors names for clarity.
Thanks for posting the original question and answer. This has dug me out of a hole. I couldn't find anything about this in the swig documentation.
let me elaborate more on the Title. Consider for example PHP_FUNCTION(session_start). Will I be able to invoke session_start from within session_id which is another PHP_FUNCTION (this is just for illustration not the actual purpose)?
Well, yes, but you should avoid it as much as possible. One of the main benefits of writing internal implementations of functions is that, contrary to what happens in PHP, C function calls are cheap. Additionally, calling PHP functions internally in C code is relatively painful.
For instance, in the case of session_start, you have php_session_start, which is exposed by the session extension. Owing to what I described in the first paragraph, extensions will usually export C functions that may be useful to others.
In fact, the internal PHP function foo needed to call the internal PHP function bar, the best strategy, if possible, would be to define an auxiliary (non PHP_FUNCTION) C function with most of the implementation of bar. Then both PHP_FUNCTION(foo) and PHP_FUNCTION(bar) could call that auxiliary function.
Anyway, the easiest way to call PHP functions is to use call_user_function:
int call_user_function(HashTable *function_table, zval **object_pp,
zval *function_name, zval *retval_ptr, zend_uint param_count,
zval *params[] TSRMLS_DC);
The variant call_user_function_ex also allows prohibiting separation when the argument should be sent by reference by it's not and specifying a symbol table.
This will work both if the relevant function is internal (PHP_FUNCTION) or was defined in userspace. If it's a regular function, you should use EG(function_table) as the first argument, the second should be NULL and I think you can figure out the others.
If you execute the function several times, this is not very efficient. In that case, see the functions in "Zend_API.h" that start with zend_fcall_.
I wouldn't recommend other options to call internal functions, such as manually setting up the arguments stack and other trickery and them manually calling the underlying C function.
ie. session_start(session_id())
Yes, however in this case it doesn't make sense because session_id() requires the session to already be started.
If Ruby gets invited to a party and brings:
foobarobject.send('foomethod')
.. and Python gets invited to the same party and brings:
getattr(foobarobject, 'foomethod')()
.. what does PHP have to bring to the party?
Bonus question: If Ruby and Python got jealous of PHP's party-favors, what English terms would they search for in PHP's documentation in order to talk about it behind PHP's back?
PHP brings this:
$foobarobject->{"foomethod"}();
... and the coke and chips.
EDIT:
Although the term for the above is variable variables there is nothing specifically talking about doing it to an object in the manual. However, you can achieve the same thing with call_user_func:
call_user_func(array($foobarobject, "foomethod"));
Using variable to hold the method name. Pretty much the same as Paolo's first example, but maybe not so obvious unless you know about it.
$method = "foomethod";
$foobarobject->$method();
You also got the Reflection classes.
$method = new ReflectionMethod('Foobar', 'foomethod');
$method->invoke(null);