PHP Pack - Combining two pack codes like perl does - php

I've been trying to figure out if the PHP implementation of Pack with statements like this.
In perl this works:
pack( 'A4/A*', "Humpty-Dumpty" );
From perl docs:
Combining two pack codes with a slash (/) associates them with a
single value from the argument list. In pack, the length of the
argument is taken and packed according to the first code while the
argument itself is added after being converted with the template code
after the slash.
in php when I try pack something like this getting error:
Warning: pack(): Type /: unknown format code
and pack return only false.
Have Someone same problems? (or custom code/library to resolve this in php)

To support perl like pack definitions I implement preprocessing of the definition.

Related

Array to string conversion in Php7

I am trying to execute this code (it was working on php5, now I'am on php7):
$this->links->$data[$te]['attributes']['ID'] = $data[$te]['attributes']['URL'];
But I get this error:
ContextErrorException: Notice: Array to string conversion
Thanks in advance
This is down to the change in how complex variables are resolved in PHP 5 vs 7. See the section on Changes to variable handling here: http://php.net/manual/en/migration70.incompatible.php
The difference is that the expression:
$this->links->$data[$te]['attributes']['ID']
is evaluated like this in PHP 5:
$this->links->{$data[$te]['attributes']['ID']}
and like this in PHP 7:
($this->links->$data)[$te]['attributes']['ID']
See https://3v4l.org/gB0rQ for a cut-down example.
You'll need to amend your code to be explicit, either by using {} as appropriate, or by breaking it down into two lines. In this case, where you've got code that works fine in PHP 5, pick the former, since it will mean the behaviour stays consistent in all versions of PHP.

Allow lack of space after function parenthesis if there is a return type hint in PHP (CodeSniffer)

I am using the MediaWiki coding standard for php_codesniffer. Thing is, that is created for PHP version <7.0.0. Let's take the following not-formatted code snippet:
function test(){}
The sniffer will report an error, that is needs space between ) and { (the rule is Generic.Functions.OpeningFunctionBraceKernighanRitchie.SpaceAfterBracket)
Now that's ok, it is normal (for me at least) to write
function test() {}
But when it comes to PHP 7 and the function has a return type hint, I want it formatted like this
function test(): string {}
So no space between ) and :, but spaces between string and other tokens there. What is the rule I have to write to achieve this?
There is already sniff for that in Slevomat/CodingStandard: https://github.com/slevomat/coding-standard/blob/master/README.md#slevomatcodingstandardtypehintstypehintdeclaration-
It is high quality package I use for over a year. They also have a branch for 3.0 ready. Also check also sniffs, they're awesome and helps with refactoring to PHP 7.0 and 7.1.

Eval code won't work

I am trying to make my own template engine, (Don't ask why!)
And will try making:
{{#Form::input("name")}}
In my rendering system i'll make this eval code:
preg_match_all('/\{\{\#(.*?)\}\}/is',$data,$output);
$out="";
foreach ( $output[1] as $variables):
$find = '{{#' . $variables . '}}';
$data = str_replace($find, eval($variables), $data);
endforeach;
But i am getting this error
Parse error: syntax error, unexpected $end in /home/psafari/public_html/slt/classes/template.class.php(43) : eval()'d code on line 1
It should run "Form::input('something')" as specificed in the template engine. What am i doing wrong?
Despite the already uber-relevant comments against building a new templating engine, I'd suggest breaking the string found. Taking your example of {{#Form::input("name")}}, you'd have {{#CLASS_NAME::FUNCTION_NAME(params)}}. So using regex you could break the found string (as you already do), create an instance of or reference the class detected, then call the method parsed using a dynamic call (and obviously fail/error if either is not found).
As for the parameters, you could avoid qualifiers (quotes in this case) and break on every comma, or use the qualifiers and parse it differently via regex again. Your call. For each parameter parsed and found, they'd be added to the function call. In order to avoid eval, and given the fact PHP does not support a random number of arguments (such as Python does with args and kwargs), having an array as the single parameter for the functions you'll use on the template files.
You could also have sort of an 'interface' function that accepts a certain number of parameters that then receives the function (or class + function names), counts the number of parameters it finds and finally relays the call to the actual underlying function based on the correct number of parameters found. Though the more you add the more obscure the processing becomes - assuming users of your templating engine will be able to define new template methods, it's a very bad idea to use this second route (as you'd have to support up to N parameters on these interface functions).

Need Help: Using SolrPhpClient in Drupal

I am using SolrPhpClient with Drupal and i want to use drupal as higher-layer user-interface to be able to query and retrieve search results from "apache solr"
I tried to use this example here (http://code.google.com/p/solr-php-client/wiki/ExampleUsage) for testing if drupal works with SolrPhpClient, but i am getting two errors which are presented below
1) Deprecated function: Function split() is deprecated in ApacheSolr_Response->_construct() (line 117 of /var/www/drupal/sites/all/modules/apachesolr/SolrPhpClient/Apache/Solr/Response.php).
2) Warning: htmlspecialchars() expects parameter 1 to be string, array given in eval() (line 80 of /var/www/drupal/modules/php/php.module(75) : eval()'d code).
Does anyone in reddit use SolrPhpClient before ? I have never used PHP so had a difficult time understanding it ?
Any kind of help will be appreciated
Many Thanks
split function is deprecated in PHP 5.3.0. So use explode function instead of split.
http://patelmilap.wordpress.com/2011/09/07/list-of-deprecated-functions-php/
And please tell me what are you passing in htmlspecialchars() function ?
It is used to Convert special characters to HTML entities.
http://php.net/manual/en/function.htmlspecialchars.php

swig-php wrapper uses pointer, c code is an array

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.

Categories