Saturday 11 February 2023

PHP 8 : leaving freedom behind for dummies .. or the version that killed PHP 🤦‍♂️

 As many developers running big production projects ..  I'm a faithful believer on two concepts : KISS & if it ain't broke don't fix it.

So .. being the late adopter that I'am and given the complexity involved in most "major version" upgrades due to backward incompatibilities and deprecated functions (for no good reason) .. I recently turned my eye into PHP 8 .. why now? well basically a Wordpress plugin kindly reminded me about upgrading .. so why not? right? off we go ...

Set everything up .. read about it .. decide which version to upgrade to .. download .. ./configure AND stop .. first bump .. a few options are no more .. a few others have actually changed from --enable to --with and viceversa .. really? seems completely stupid thing to do .. but hey! it's the new PHP must be worth it! .. pass that bump .. compile .. install .. NO PEAR .. bump .. redo --with-pear (although not properly documented) .. 'cause one must assume for  Thies C. Arntzen, Stig Bakken, Shane Caraveo, Andi Gutmans, Rasmus Lerdorf, Sam Ruby, Sascha Schumann, Zeev Suraski, Jim Winstead, Andrei Zmievski it must be much more fun to rebuild all those extensions from scratch right? .... 


Anyhow .. I'm past the install process and now to check our test unit .. WARNING WARNING WARNING !!!! FATALITY ... our first typecasting issue arises : substr("3XYZ",0,1)-1can no longer be understood ... wait .. what? .. that can't be .. PHP IS SMART !! (well at least used to be) .. that's one of the VERY FEW PERKS of still working with PHP : typejuggling (string)"3" - (int)1 = (int)2 because PHP KNEW that an arithmetical operator implied a numeric context ... but noooo ... now the PHP geniuses decided that there is no way that "3"-1 can be interpreted as =2 and now they REQUIRE US to typecast thousands of lines of code OR decide not to upgrade at all because for some reason they were unable to make this a WARNING .. a feature that has been used since PHP was conceived is now not just a bug but a FATAL ERROR that will not allow your code to run at all.


So .. anyways .. lets jump over this hoop and see what other errors may lurk beyond this typecasting UTTER NONSENSE .. and let me be clear .. they could've made this a WARNING or a NOTICE .. but they decided to make this a FATAL ERROR .. no wonder why only 3% of PHP users worldwide have adopted it .. most if not all major production projects won't typecast thousands of lines of code.


On our test unit I decided to clean up the code and leave just tiny part & fix the errors to find out if that was that .. LOL .. hell no .. guess what .. arrays!! .. another one of the most basic structures of any project : asort now throws a FATAL ERROR:


[PHP8] TypeError : asort(): Argument #1 ($array) must be of type array, null given.


!!! regardless of using an error supression operator @ !!!!


Obviously this error applies to any function that deals with arrays not just the sorting family .. weeeell that was that for me .. if this was a simple taste of what will need to be done to hundreds of files and  hundreds of thousands of lines of code .. I will not even try to figure what comes after that.. nope. 


I will be recommending going a different a path and implementing a different language altogether given the need to basically recode everything .. then let's recode on a more futureproof language that will hopefully not force it's users to recode everything on a whim from a bunch of people just to add a few additional features that definitely do not make for what they brake : dumb union types + JIT vs years and years of lines of code and coding paradigms.


No wonder Wordpress has begun shifting all their code to NodeJS and Microsoft decided NOT TO SUPPORT PHP8 in any way. Turning PHP into Java or anyother close minded squared nonsensical language that requires the coder to code more instead of less is a BIG no-no, it simply IS NOT THE WAY.


Saturday 9 February 2013

PHP Convert HEX <- 2 -> Floating point (Removed from PHP.net)

This article was removed from PHP.net notes because it was to big.. hell.. it's just two 30 line fucntions! 

Hey PHP.net guys! If you would've compiled this function into php there would'nt be a need for me or anyother looking for this to have it as a note =)

There are many scripts/functions to convert a Hex string to a Floating point number, but i could'nt find any usable function to convert a float2hex (float number to hexadecimal) .. so i went on an made one! .. to my surprise.. it didn't matched the other existing functions results exactly due to different methods used on each .. so i went on an created a complementary function to have both results match float2hex32n<->hex2float32n.


<?php/** Complementary functions to CONVERT PHP FLOATING POINT NUMBERS or DECIMALS
* (IEEE 754 single-precision 32 bit) TO HEXADECIMAL AND BACK.
*

* @created on 28/Jan/2010 / time spent: 2hours approx.
* @special thanks to Thomas Finley's article "Floating Point"
*
http://tfinley.net/notes/cps104/floating.html
*
* These functions allow to convert any php floating point numbers with the
* notation 1.234 (or fixed point numbers) into their corresponding 8 digits
* hexadecimal notation. (i.e.- 1557897.40 -> 49BE2C4B <- 1557897.40) by
* disregarding their implicit format and treating them at will as either
* integer, decimals, binary numbers, hexadecimal values, or plain text.
*
**/

/** FLOAT2HEX32n
* (Convert php float numbers or decimals (single-precision 32bits) to 8 digit Hexadecimal)
* Accepts only fixed point notation decimal numbers or fractions on a string (i.e.- "1.23456")
* @usage:
* float2hex32n("-1557897.13"); returns "c9be2c49"
**/
function float2hex32n($number) {
//Convert non-decimal to decimal.
$number=number_format($number,23,'.',''
);
//Get the integer portion of $number
if ($number>0
) {
$intnumber=substr($number,0,strpos($number,"."
));
} else {
//Check whether is a negative number to remove - sign.
$intnumber=substr($number,1,strpos($number,"."
));
}
//Convert integer to binary
$binint=decbin($intnumber
);
//Get the decimal fraction of the number
$pointnumber=substr($number,strpos($number,"."
));
//Add a 0 to treat as single decimal fraction
$pointnumber="0".$pointnumber
;
//Convert decimal values to base 2
$tmppoint=number_format($pointnumber*2,23,'.',''
);
for (
$i=0; $i<23; $i
++) {
$binpoint.=substr((string)$tmppoint,0,1
);
$tmppoint=substr((string)$tmppoint,1
);
$tmppoint=number_format($tmppoint*2,23,'.',''
);
}
//Gather both values to get base 2 binary fraction
$scibin=$binint.".".$binpoint
;
//Find fraction separator "." position
$exp=strpos($scibin,"."
);
//Transform to scientific notation (1.x^exp)
$scibin=substr($binint,0,1).".".substr($binint,1).$binpoint
;
//Create mantissa
if ($scibin>1
) {
$mantissa=substr($scibin,2
);
} else {
$mantissa=substr($scibin,1
);
}
//Fill mantissa to 23 bit value
$fill23=23-strlen($mantissa
);
for (
$i=0; $i<$fill23; $i
++) {
$mantissa.="0"
;
}
//Convert fraction separator position to exponent value
if ($exp>0) { $exp
--; }
//Adjust to binary notation exponent value
$exp+=127
;
//Convert to 8 bit binary
$exp=decbin($exp
);
//Find 1 bit sign value
if ($number>0) { $sign=0; } else { $sign=1
; }
//Compose final binary value
$binfinal=$sign.$exp.$mantissa
;
//Reorganizae number into 4digit/bits packets and
//finally convert to decimal value and to hex.
$hexfinal.=dechex(bindec(substr($binfinal,0,4
)));
$hexfinal.=dechex(bindec(substr($binfinal,4,4
)));
$hexfinal.=dechex(bindec(substr($binfinal,8,4
)));
$hexfinal.=dechex(bindec(substr($binfinal,12,4
)));
$hexfinal.=dechex(bindec(substr($binfinal,16,4
)));
$hexfinal.=dechex(bindec(substr($binfinal,20,4
)));
$hexfinal.=dechex(bindec(substr($binfinal,24,4
)));
$hexfinal.=dechex(bindec(substr($binfinal,28,4
)));

return
$hexfinal
;
}
/** Using either function will return a value which can be used on the other function
* to return the original input. (Hope it helps =)
**/
?>

 


Second function (HEX2FLOAT32n) converts Hexadecimal 8 digit strings to fixed decimals float numbers. (complementary to FLOAT2HEX32n above)

<?php /** Complementary functions to CONVERT PHP FLOATING POINT NUMBERS or DECIMALS
* (IEEE 754 single-precision 32 bit) TO HEXADECIMAL AND BACK.
*

* @created on 28/Jan/2010 / time spent: 2hours approx.
* @special thanks to Thomas Finley's article "Floating Point"
*
http://tfinley.net/notes/cps104/floating.html
*
* These functions allow to convert any php floating point numbers with the
* notation 1.234 (or fixed point numbers) into their corresponding 8 digits
* hexadecimal notation. (i.e.- 1557897.40 -> 49BE2C4B <- 1557897.40) by
* disregarding their implicit format and treating them at will as either
* integer, decimals, binary numbers, hexadecimal values, or plain text.
*
**/

/** HEX2FLOAT32n
* (Convert 8 digit hexadecimal values to fixed decimals float numbers (single-precision 32bits)
* Accepts 8 digit hexadecimal values on a string (i.e.- F1A9B02C) and single integer to fix number of decimals
* @usage:
* hex2float32n("c9be2c49",2); returns -> "-1557897.13"
**/
function hex2float32n($number,$nd) {
//Separate each hexadecimal digit
for ($i=0; $i<strlen($number); $i
++) {
$hex[]=substr($number,$i,1
);
}
//Convert each hexadecimal digit to integer
for ($i=0; $i<count($hex); $i
++) {
$dec[]=hexdec($hex[$i
]);
}
//Convert each decimal value to 4bit binary and join on a string
for ($i=0; $i<count($dec); $i
++) {
$binfinal.=sprintf("%04d",decbin($dec[$i
]));
}
//Get sign 1bit value
$sign=substr($binfinal,0,1
);
//Get exponent 8bit value
$exp=substr($binfinal,1,8
);
//Get mantissa 23bit value
$mantissa=substr($binfinal,9
);
//Convert & adjunt binary exponent to integer
$exp=bindec($exp
);
$exp-=127
;
//Assign mantissa to pre-scientific binary notation
$scibin=$mantissa
;
//Split $scibin into integral & fraction parts through exponent
$binint=substr($scibin,0,$exp
);
$binpoint=substr($scibin,$exp
);
//Convert integral binary part to decimal integer
$intnumber=bindec("1".$binint
);
//Split each binary fractional digit
for ($i=0; $i<strlen($binpoint); $i
++) {
$tmppoint[]=substr($binpoint,$i,1
);
}
//Reverse order to work backwards
$tmppoint=array_reverse($tmppoint
);
//Convert base 2 digits to decimal
$tpointnumber=number_format($tmppoint[0]/2,strlen($binpoint),'.',''
);
for (
$i=1; $i<strlen($binpoint); $i
++) {
$pointnumber=number_format($tpointnumber/2,strlen($binpoint),'.',''
);
$tpointnumber=$tmppoint[$i+1].substr($pointnumber,1
);
}
//Join both decimal section to get final number
$floatfinal=$intnumber+$pointnumber
;
//Convert to positive or negative based on binary sign bit
if ($sign==1) { $floatfinal=-$floatfinal
; }

//Format float number to fixed decimals required
return number_format($floatfinal,$nd,'.',''
);

}
/** Using either function will return a value which can be used on the other function
* to return the original input. (Hope it helps =)
**/
?>



Note: manasseh@smartconputerinc.com wrote:

I found that 00000000 hex was converting to 1.0 decimal. From the Wikipedia article on IEEE-754 floating point:

The true significand includes 23 fraction bits to the right of the binary point and an implicit leading bit (to the left of the binary point) with value 1 unless the exponent is stored with all zeros.

In hex2float32n, replace:

$intnumber=bindec("1".$binint);

with

if ($exp <> -127)
{ $intnumber=bindec("1".$binint); };

and then 00000000 works correctly without affecting "normal" numbers.

Sunday 4 December 2011

What does an IT pro actually do? Bing or Google translate paid services?

S#*t! .. to begin with .. i just lost the beginning of this post which i started typing as a Facebook update LOL!

Many wonder what those nerdy guys do if everybody know how to use a computer right? Well .. hopefuly none of those guys spent X amount of years in college (or similar) just to learn how to use a computer! Damn.. losing out on those par(n)ties .. sad ... ^^

Well, i for one, i'm not the nerdy type. Actually, i'm considered by my friends, peers & family as the complete opposite. Nobody really knows what i do, but they do notice, from time to time, when after spending days literally glued to my computer screens (yes, plural^^) to what i suspect my stepfather thinks as "fooling arround with the computer" that at any given time of day i go "out" and most times don't come back 'till the next morning. Yes i like, nah, let me correct that, i loooove to party! lol.

I'm losing myself on small talk, let me get you back to what i intended this post to be: an explanation of what a guy like me does when it's glued to the computer.

This all started last thursday 1st of December 2011 when Google decided (after a long 4 months notice i must say) to deprecate it's free Google Translate Api v1 for the newly and not free v2. I received a call at 4 in the morning from my dear friend and business partner in Spain letting me know that the system was not working - not working? what do you mean? - look at it he says, no info is coming out on most of the system. Dang! - clients are already freaking out for they can't show their properties to their clients!!.

4am, a quick look at the system to find out what was wrong: the translation service was no longer translating and was returning empty strings (i.e.- nothing at all) oooops!!!!

Nothing like a good shock to wake you up! .. well, hands on, let's try to find a quick translate alternative .. nah.. nothing quick at hand.. ok, let's pay the mtf's @ google to have this sorted out in the meantime  .. setting up the billling method, pay by credit card, ok let's make it work!! .. ooops! ... can't do! must rewrite the whole code!! S#'t!!!!!!!!!!! .. half hour has gone past .. clients are still unable to fetch anything at all!! .. really? how hard can it be to "port the code" from v1 to v2 .. dig onto it a bit further .. come on.. can't be that hard .. LOL!!!!!

Another half hour gone, it's time to take action, clients can't be left hanging or else they will let me hanging and go elsewhere! Ok, take the translation scripts out, rewrite them not to take into account any translations .. PIA job, rewrite scripts on 100+ files one by one ...

Two hours later during which i seriously thought about google business strategy and how they (Google) went from beeing a cool company offering free options to the world, open source software and equal opportunity to all, to being a behemoth, a goliath in all the sense of the word, a giant oppresing the good and hard working IT people like me ^^. Two hours that i spent envying them, and, what is commonly refered in Spain as "cagandome en sus puñeteros muertos!" and the job was done, no more auto-translation but data access is ok.

Google wins. I realize they have me (us, everyone) by the balls. Their will is our command.com

Anyways, after our clients had access back to their stuff, i decided it was time to go back to bed ^^.

Friday passed by without incident and research begun ... yes.. all that time we spend on the computer is not really looking at Facebook updates you know .. research, creation, development or plain old tedious repetitive work is what takes 99% of the time we spend in front of a computer. (Ask any decent IT guy and what they'll say is: NO, i dont want to spend my free time in front of a computer)

So, after a couple of hours of looking (research) at all the useless alternatives, it all got back to the same old same old .. Google or Microsoft .. both require further reading and learning on their newly (at least for me) v2 API's (Application Programming Interfaces) in order to get back the awe inspiring feature with a set of flags that will translate whatever anyone writes into a dozen different languages effortlessly on our system.

Eat, pray, love, take a dump, and back it is ... learn the new stuff. Dig into pages and pages of documentation of both providers to only grasp the surface of what their new, more powerful, more complete API's do. And yes, also take into consideration those few courses of financing you got at school and life to figure out what's the best option. In the end for me is a mixture of both: Bing offers better pricing in bulk for large translations (more than two paragraphs that is) and Google offers better tools for quick translations (though it's more expensive for bulk).

So now that translation is no longer free, i must pre-translate all the info on the database once (through Bing service) and offer that nice real-time translation service for emails through Google's paid translation. In the end, it all means i'll have to throw a couple of houndreds more each month!! for a service that was free and through which i built upon offering my clients such remarkable features just because it was free ... Now, for me as for most programmers that built upon Google services because they were free, our clients have come to like, love and rely on such features, so .. the natural thing to do is to keep them regardless of the cost it may involve.

I tweet the following: #Googletranslate api down 4ever, time 2think about what other "free" srvcs they'll let you build upon & then start charging! p.s.- follow me @nstiac @n2works =)

No wonder Google guys get richer and richer .. any resemblance to physical(fiscal) reality is no coincidence: Give them something free until they really really rely on it, then start charging people (more) for it: highways, water, owning a car, TV in some countries, etc.. Google translate api ^^

Well that was all just thursday night and friday ... yes.. notice any gaming? any went to the movies? bowling? watched the game? .. nop.. none of that.. just facing the computer & not fooling arround on it as you can see.

If you've read all the way to here, let me get to the part where no "my son is a genious with powerpoint" kid can actually accomplish and what any decent IT pro actually does:

Wakeup saturday morning and let's get hands on to actually getting the new API's to work. A quick look at google's "copy & paste" example to realize it's a laughable attempt of example for a real-world application: dynamically append scripts to the header for each translation. Let me try to explain why this is pure bulls#!t. In real life, no one pre-thinks everything they'll say (speak) throughout the day .. so basically google's example is to pre-record everything you'll say and carry it with you on a "one-time" recording machine. If it were to be the case that throughout the day you'd need to say something you haven't recorded, you'd need to purchase another one time recorder for whatever you just thought you needed.. so.. throughout the day.. you'd end up with several houndreds of recording machines (remember they are one-time recorders so you need one for each time you forgot or actually needed a new recording)..so, regardless of the weight it would take on the last hours of the day to carry let's say 20 recording machines on you, the price tag of that would be ridiculous at the end of the month when you've bought 600 recording machines right? well.. you get the idea .. so here is where creation comes in: you need to devise (create) a nice multi-recorder that suits your needs (or in IT terms: a single script that can handle & pass queries to google's REST service without leaking memory by stacking code onto the client's header.)

It's not that it is like creting the wheel all over again, but definetely nobody needs the same wheel size, thus everybody needs a different wheel, thus i need to create my own wheel (script) .. it turns out that with a little knowledge in scripting languages it turned to be ready in a breeze (a couple of hours for the whole shebang, notice i personally needed different wheel sizes myself so i created what can be thought of an automatized wheel factory^^) .. yey!! one down, one to go.. still need to work on Bing's script, another hour or so i naively thought.. lol!!!

Turns out that Microsoft, being Microsoft, codes only on their propietary programming languages (ASP & C# to be more precise) therefore no information relating common sense and freely available scripting languages is available in their site. Furthermore, Microsoft, being Microsoft, nobody else does Microsoft, so little or no information is available elsewhere on working their API through open source multi-plattform languages. Hell!!! To make matters worse, i can not use the easypeasy widely used example for it's not meant for the pro (fee based) service which i need and which requires OAP authentication (a largely succesfull attempt at complicating things) through a mixture of time-sensitive tokens and header manipulation. Damn it Microsoft, KISS!! what about making things easier for people to use? KISS stands for Keep It Simple Stupid!

So.. give it a go.. try with simple javascript, no luck (javascript OAP implementation requires global server modifications that does not comply with anything else that a server must do but to work only with their API and leave everything else useless) .. one hour has gone by .. try with jQuery ..after much trial and error and finding their documentation is flawed (parameter clientId needs to actually be client_id) i finally got a 200 OK response .. it's empty!.. damn! .. something must be wrong .. again & again .. yup! no way of actually receiving their POST back for the mechanism used to actually get the translation result is not yet implemented in jQuery .. they do have a getJSONP but Microsoft decided to complicate things by accepting POST queries only (which no fu#[ing body does anymore) ... another hour and half gone by .. oh.. and i must let you guys know that this is all only to be able to retrieve the authorization key which i need to get every 10 minutes or so.. i haven't actually done anything to even try to get a translation back.

Ok, so i cant get the key client-coded, think.. think.. (research).. let's try to get it server-coded, send the POST directly from the server instead of sending it from the browser ... several methods come to play, most of them discarded right away due to the level of cross-scripting complication they require (use pearl script, cgi, c? .. for a simple web-based app? nah.. lets try it with PHP .. curl.. dig the manual .. (more research) .. another hour goes by, trial & error, search existing examples, nobody shares! lol .. finally got it!!!!!! yeeeeeeeyyyyy!!!!!!!! got the key.. it's not a key.. it's a largely complicated mix of urls & data. KISS!!!!!

Right, so the complicated authentication part apart, the rest should be fairly easy .. WRONG! .. i remembered again why i dont like nor use Microsoft products whenever i can .. tried client scripting without success... antoher hour & half has gone by .. allthroughout 4 or 5 hours gone with this Bing translator ultra new & better performing API!! and no results yet. No documentation, nowhere to go, asking on a forum? LOL .. best answers are ask to a supervisor whom replies 4 weeks later with.. do you still have the issue? .. k .. let's go with server-side .. shouldn't be server side .. need my clients to work on-the-fly not click-wait-get-clickagain-wait-get ... ahh!! i remembered i'm using Bing for bulk database translation not on the fly .. whooo! i'd be damned if i had to rely on Bing for that .. ok .. server sided it is ... REST is bull .. HTTP is not useful server-sided .. go with SOAP .. need to recompile the server's apache & php to enable SOAP over PHP .. done .. cool right? (well... i guess i do have some nerd on me =) ...  a couple of attempts later.. got it!!!!!

Sheiße !!! 8-9 hours to get Bing translate to work .. 1-2 hours to get Google's to work ... that should tell somebody something about both providers ..

Google script template:

<script>

//  @created on 03/Dec/2011 / time spent: 1.5hours approx.

var apiKey = "xxxxxxxxxxxxxxxxxxxxxxx";
var langSource = "es";
var langTarget = "it";
var apiurl = "
https://www.googleapis.com/language/translate/v2?key=" + apiKey + "&source=" + langSource + "&target=" + langTarget + "&q=";
var text = 'This is a test string';
  
function translate(text) {

jQuery.ajax({
    url: apiurl + encodeURIComponent(text),
    dataType: 'jsonp',
    success: function(data) {
  dosomething

     }
});

}
</script>


Bing translate PHP w/OAP access token script:

<?

// @created on 03/Dec/2011 / time spent: 9.5hours approx.
function request_new_token() {
 $obj_connection = curl_init();
 $arr_query_bits = array (
 'client_id' => 'numbersOnly!!!',
 'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
 'scope' => 'http://api.microsofttranslator.com',
 'grant_type' => 'client_credentials'
 );
 $str_query = http_build_query($arr_query_bits);

curl_setopt($obj_connection, CURLOPT_URL, 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13');
curl_setopt($obj_connection, CURLOPT_HEADER, 0);
// curl_setopt($obj_connection, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($obj_connection, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($obj_connection, CURLOPT_POSTFIELDS, $str_query);
curl_setopt($obj_connection, CURLOPT_POST, TRUE);
curl_setopt($obj_connection, CURLOPT_TIMEOUT, 1);

$str_response = curl_exec($obj_connection);
curl_close($obj_connection);

$matches = array();
preg_match('/\"access_token\":\"([^"]+)\"/', $str_response, $matches);
$token = $matches[1];
preg_match('/\"expires_in\":\"([\d]+)\"/', $str_response, $matches);
$expires = $matches[1];

return array($token, $expires);
 }

$token=request_new_token();


$str_auth_header = "Authorization: Bearer ". $token[0];
ini_set('user_agent', 'PHP-SOAP/' . PHP_VERSION . "\r\n" . $str_auth_header);


$arr_context = array('http' =>
  array(
      "header"  => "Authorization: Bearer " . $token[0]
  )
);

$arr_options = array (
   'soap_version' => 'SOAP_1_2',
   'encoding' => 'UTF-8',
   'exceptions' => true,
   'trace' => '1',
   'cache_wsdl' => 'WSDL_CACHE_NONE',
   'stream_context' => stream_context_create($arr_context)
);

$obj_connection = new SoapClient('http://api.microsofttranslator.com/V2/SOAP.svc', $arr_options);
$str_soap_action = 'Translate';
$arr_request_arguments = array (
   'appId' => '',
   'text' => utf8_encode('This is a test'),
   'from' => "en",
   'to' => "es"
);

$obj_soap_response = call_user_func(array($obj_connection, $str_soap_action), $arr_request_arguments);
$str_result = $obj_soap_response->TranslateResult;


echo utf8_decode($str_result);


?>


LOL!!!! 2 days work for grabs .. this is what we IT pro's do .. no gaming .. no constant facebook .. no twitter all day long .. just plain old work. cheers =)

p.s.- Ask any computer savyy kid if he really understands any of this ^^