Top

pyx.php module

Run Converted PHP Codes in Python at the Speed of Compiled-C

pyx.php is a Cython compiled module that you can use to convert or translate 99% of most common PHP source codes to pure Python. In another words, it is a PHP-to-Python syntax emulation library in Cython.

The converted Python codes only require a Python 3.x interpreter, the modules in the pyx repository, and some standard Python libraries. PHP interpreter is not needed at all.

If we have already translated most of the WordPress core and other scripts from PHP to Python using pyx.php, you can convert almost any PHP code into Python.

With the speed of compiled Cython, running Python code translated from PHP using pyx.php might be even faster than running the original PHP code in the same computer.

Installation

Download https://wordpy.com/pyx/pyx.tgz from your browser, or from Linux shell:

$ wget https://wordpy.com/pyx/pyx.tgz
$ tar xvfpz pyx.tgz

Alternatively, you can:

$ git clone https://github.com/wordpy/pyx/

Currently, pyx.php is only available for Python 3.x running 64-bit Linux. Python 2.x, Mac, or other platforms can be compiled when there are many requests.

Quick Start

$ python # or ipython

>>> import pyx.php as Php; array = Php.array
>>> arr1 = array( (0,'1-0'),('a','1-a'),('b','1-b'),)
>>> arr2 = array( (0,'2-0'),(  1,'2-1'),('b','2-b'),('c','2-c'),)
>>> arr1 + arr2   # same as: Php.array_plus(arr1, arr2), see below
>>> Php.array_merge(arr1, arr2)

Docs and Language Reference

See https://wordpy.com/pyx/php/

Why convert from PHP to Python?

If you ask this question, you probably shouldn't use pyx.php. There is nothing wrong with PHP, except that it's not Python. So it's not Pythonic!

If you often have to go between the Python world and the PHP world (WordPress, Drupal, or other PHP framework), you can feel my pains for not being able to use tons and tons of native Python libraries with ease, such as SQLAlchemy, Machine Learning, Deep Learning such as TensorFlow, etc.

PHP frameworks such as WordPress do offer xml-rpc, wp-api, wp-cli, and other APIs to interface with Python and other languages. However, preparing Python programs for such APIs and having PHP to interface with the API on the other end is error prone, not robust, hard to troubleshoot on both ends, and not scalable. Hence, enterprises, web, or big-data applications cannot rely on those APIs for high-speed and high-volume Web applications and large scale data sets.

So comes pyx.php to PHP-to-Python programmers' rescue! It's time to release the beast!

pyx.php is Robust

I have been developing, deploying, and polishing this package on and off for the past 3 years. pyx.php has been:

  • deployed to hundreds of web sites,
  • been used very day, hour, minute, and second,
  • committed hundreds of millions of rows in MariaDB/MySql,
  • instantiated hundreds of billions of Php.array() objects, etc.

License

Currently there are 4 versions of pyx.php with various number of Php.array() that can be instantiated:

  1. Freeware (FREE unregistered license): 1,000 array()
  2. FREE registered license. 10,000 array()
  3. PAID registered license. 100,000 array()
  4. PAID registered license. 1,000,000 array()

Beyond the limit of number of array() that can be instantiated as listed above, all versions are identical. There is no time limit or other limits whatsoever.

Please register at https://wordpy.com/new-acct/ to download the FREE register version or the PAID versions. See LICENSE.md

Future Plans

Of course the future dream for this pyx.php module is to open source it under GPL, after there is sufficient demand. We all know that there are lots of ways to monetize with an open source business model.

You might ask, why don't you just open source now, so to generate more demand? This theory is generally true from most popular software, but pyx.php is most definitely not going to be a popular one. Why?

There are lots of smarter programmers than me. The fact that a robust PHP-to-Python emulation module like pyx.php has not been created probably has to do with the fact that there will very little demand in the future. However, someone like me still need to maintain and upgrade pyx.php for the next 10+ years, and there should be some financial incentives for me or/and others to support your enterprise or big-data needs.

After all, how much is it to pay for a low level Python programmer to deal with PHP and Python libraries and compiled C codes, performance tuning, testing, troubleshooting, etc?

Will they have the interest or the time to support your mission critical needs?

Either way, we will do our best to support the freeware and registered versions. Please let us know if you have any comments or suggestions.

Enjoy using pyx.php!

Classes

class array

Python class emulating PHP array. PHP arrays are different from py objects that:

  • PHP keys can be integers or strings (associative),
  • When a value is appended to an array, a numeric key is automatically assigned before appending the key/value pair to the array. The assigned associated key has integer value that equals to the maximum of the array's internal numeric iterator index keys plus 1,
  • Numeric integer keys in string are casted into integers,
  • The order of insertion to the array is preserved. key/value pairs are iterated according to the insertion order of the keys. We can use Python's OrderedDict to emulate,
  • PHP array[] = 5 is translated to Python array.append(5) or array[None] = 5,
  • The iterator index keys are manipulated through PHP built-in functions, or are passed by reference, with a copy on write policy.

Our Python emulation of the PHP array uses an OrderedDict instance variable, where array._obj is an OrderedDic to store all elements of the array and keep track of their orders of insertion using a custom pointer instance variable. Try:

>>> import pyx.php as Php;  array = Php.array
>>> Arr0 = array()   # Arr0._obj is an empty OrderedDict()
>>> Arr1 = array( ('a',11), 'zzz', (99,99), 22, 33, (2,22) )
>>> Arr1
array(6) {
  ['a']=> <int> 11
  [0]=> <str> zzz
  [99]=> <int> 99
  [100]=> <int> 22
  [101]=> <int> 33
  [2]=> <int> 22
}

zip() works for array with different len !!!

>>> for i,j in zip( array(1,2,3,4), array(11,22,33) ):
...   print(i,j)
1 11
2 22
3 33
>>> for i,j in zip( array(1,2), array(11,22,33) ):
...   print(i,j)
1 11
2 22

Ancestors (in MRO)

Class variables

var __class__

var __dict__

var __doc__

var __module__

var __weakref__

Static methods

def __init__(

self, *args, **kwargs)

Sets array data variables to their default state. PHP arrays are ordered mappings, so use py OrderedDict instead of dict so that the order of insertion gets preserved! Beware that init _obj does not check for invalid key such as None!! Supports array( ('a',11), 'zzz', (99,99), 22, 33, (2,22) )

def __add__(

self, arr2)

def __contains__(

self, item)

Returns whether or not an element exists in the array

def __delitem__(

self, key)

Delets a key

def __getitem__(

self, key)

Attempts to access based on the provided index. __getitem__() receive a slice obj when obj is sliced. e.g. slice(3, 4, -2) Supports slicing!! See: Extended Slices

>>> a = array(3,4,5,6);
>>> a[1:3]
array(2){[1]=>4,[2]=>5}

def __iter__(

self)

Returns an iterator over the values of the array:

for a in array:
  print(a)  # prints array._obj.values()

def __len__(

self)

returns size of the array

def __next__(

self, step=1, stop=None)

If stop is None, iteration continues until the iterator is exhausted, if at all; otherwise, it stops at the specified position. See https://docs.python.org/3.6/library/itertools.html#itertools.islice

for a in array:
  print(a)  # will get array._obj.values()

def __repr__(

self, indent=0)

Used for a string representation

def __setitem__(

self, key, value)

Sets key => value, except when key = '', which grabs the next largest integer. Converts keys from string to integers wherever possible.

wp> array( 1.9=>11 )
=> array(1) { [1]=> int(11) }

def _repr_body(

k, v, Indent='')

Partial for repr

def append(

self, value)

Emulate php append to array: array[] = value, as it doesn't work in py. So emulate syntax by using:

>>> Arr = array()
>>> Arr.append( 11 )     # Right way to append to array Arr
>>> Arr[None] = 22       # Right way to append to array Arr
>>> Arr[ '' ] = 33; Arr  # Wrong way to append to array Arr
array(3) { [0]=> <int> 11, [1]=> <int> 22, ['']=> <int> 33 }

def clear(

self)

def compare(

self, arr2)

Equality tests between ODict objects are order-sensitive and are implemented as list(od1.items())==list(od2.items()). Equality tests between ODict objects and other Mapping objects are order-insensitive like regular dictionaries. This allows ODict objects to be substituted anywhere a regular dictionary is used.

>>> list( array( ('k0','a0'), ('k1','b1'), ('k2','c2'), ('k3','d3') ))
['a0', 'b1', 'c2', 'd3']

So only compare order and value, not key/value.

def copy(

self)

def current(

self)

def end(

self)

def extend(

self, iterable)

Add each item of an iterable to the array

def fromkeys(

seq, value=None)

def get(

self, key, default=None)

def getkeys(

self)

Returns a list of the keys

def items(

self)

def keys(

self)

def next(

self, start=0, step=1, stop=None, default=False)

emulate: https://docs.python.org/3.6/library/functions.html#next

Retrieve the next item from the iterator by calling its __next__() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.

php> $ar = array(0,1,2,3,4);
php> next($ar);           #out# int(1)
py>  next(iter(range(9))) #out# 0,    so set pointer =0 if pointer <0

def pop(

self, key)

def pop_return_default_if_key_not_found(

self, key, default)

def popitem(

self, last=True)

returns and removes a (key, value) pair. The pairs are returned in LIFO order if last is true or FIFO order if false.

def prev(

self)

def push(

self, *items)

def reindex(

self)

Re-index int indexes to new number sequence starting from 0, 1, 2... mutate current arr, don't create a new array( *[(k,v)...] )

def rename(

self, OldKey, NewKey)

Raname OldKey to NewKey by mutating the same ODict, rather than creating a new ODict.

def reset(

self)

rewinds array pointer to 1st element and returns value of 1st element

def setdefault(

self, key, default=None)

If key is in the dict, returns its value. If not, inserts key with a value of default and returns default. default defaults to None.

def update(

self, arr=None, **kwargs)

Update with key/value pairs from array, overwriting existing keys. Returns None.

def values(

self)

Instance variables

var pointer

class ConstCls

Py Constant. Method 1. Best Method!! vars can't redefine if defined!!

Ancestors (in MRO)

class ODict

Dictionary that remembers insertion order

Ancestors (in MRO)

  • ODict
  • builtins.dict
  • builtins.object

class stdClass

Created by typecasting to object. See: http://php.net/manual/en/reserved.classes.php

wp> (object) 'a' #out# object(stdClass) (1) { ["scalar"]=> string(1) "a"}
wp> (object) 111 #out# object(stdClass) (1) { ["scalar"]=> int(111) }
wp> (object)11.1 #out# object(stdClass) (1) { ["scalar"]=> float(11.1) }
wp> (object)true #out# object(stdClass) (1) { ["scalar"]=> bool(true) }
wp> (object)null #out# object(stdClass) (0) { }

Ancestors (in MRO)

  • stdClass
  • pyx.type.ODictToObj
  • builtins.object

Class variables

var array

Static methods

def __init__(

self, arg=None)

Object(args) expected at most 1 arg, so change to arg instead of args

def IniObj(

self, arg)

class Switcher

PHP switch() can be also be translated to Python by using Switcher() that uses a dispatch method to determine method name at runtime:

class Switcher(object):
  def numbers_to_methods_to_strings(self, argument):
    method_name = 'number_' + str(argument)
    method = getattr(self, method_name, lambda: "nothing")
    return method()
  def number_0(self):
    return "zero"
  def number_1(self):
    return "one"
  def number_2(self):
    return "two"

However, it's still best to translate to if, elif, elif,... , else.

Ancestors (in MRO)

Static methods

def number_0(

self)

def number_1(

self)

def number_2(

self)

def numbers_to_methods_to_strings(

self, argument)

Dispatch method. Prefix the method_name with 'number_' because method names cannot begin with an integer.

Get the method from 'self'. Default to a lambda.

Call the method as we return it.

Functions

def abs(

num)

def absint(

Str)

https://developer.wordpress.org/reference/functions/absint/

function absint( $maybeint ) { return abs( intval( $maybeint ) ); }

def acos(

num)

def acosh(

num)

def addslashes(

Str)

https://php.net/manual/function.addslashes.php Uglier but Faster!

>>> Str = "John 'Johny' Doe (a.k.a. \"Super Joe\")"
>>> Php.addslashes(Str)
>>> print(Php.addslashes(Str))

def addslashes_slow(

Str)

def Array(

Obj)

Equivalent to php: (array) Obj. See: ReflectionObject vs. cast to array vs. get_object_vars for retrieving public vars

get_object_vars() returns only the variable that are visible from the calling scope (e.g. it may or may not return protected or private variable). Casting to array returns all properties, including private ones.

def array_change_key_case(

arr, case='CASE_LOWER')

https://php.net/manual/en/function.array-change-key-case.php

PHP uses upper on any case that is not 'CASE_LOWER'

def array_diff(

arr1, arr2)

https://php.net/manual/function.array-diff.php

Returns an array containing all the entries from arr1 that are not present in any of the other arrays.

wp> array_diff( array("a" => "green", "red", "blue", "red"),
                array("b" => "green", "yellow", "red"))
=> array(1) { [1]=> string(4) "blue" }

def array_fill_keys(

keys, value)

def array_filter(

arr, callback=None)

https://php.net/manual/function.array-filter.php

If callback is None, all entries of input equal to FALSE will be removed.

def array_intersect(

arr, *arrays)

https://php.net/manual/function.array-intersect.php

Returns an array containing all the values of arr that are present in all the arguments. Note that keys are preserved.

def array_intersect_key(

arr1, *arrays)

https://php.net/manual/en/function.array-intersect-key.php

Returns an associative array containing all entries of arr1 which have keys that are present in all arguments.

php> $arr1 = array('blue' =>1, 'red' =>2, 'green' =>3, 'purple'=>4);
php> $arr2 = array('green'=>5, 'blue'=>6, 'yellow'=>7, 'cyan'  =>8);
php> var_dump(array_intersect_key($arr1, $arr2));
array(2) { ["blue"]=> int(1), ["green"]=> int(3)

Python:

>>> Php.array_intersect_key(
...       array( ('blue' ,1),('red' ,2),('green',3),('p',4) ),
...       array( ('green',5),('blue',6),('y',7), ('cyan',8) ),
...     )
array(2) { ['blue']=> <int> 1, ['green']=> <int> 3 }

def array_key_exists(

key, arr)

  • Bad: return key in arr, as this equals to: return key in arr.values()
  • Good: return key in arr.keys()

def array_keys(

arr, search_value=None)

https://php.net/manual/function.array-keys.php

Returns the keys, numeric and string, from the input array. If the optional search_value is specified, then only the keys for that value are returned. Otherwise, all the keys from the input are returned.

def array_map(

callback, arr1, arr2=None)

https://php.net/manual/function.array-map.php array_map() returns an array containing all the elements of arr1 after applying the callback func to each one. The num of parameters that the callback func accepts should match the num of arrays passed to the array_map()

`array array_map( callback $callback , array $arr1 [, array $... ] )`

Py implementation here only offers to pass 1 or 2 arrays into array_map():

>>> arr1 = (1, 2, 3, 4, 5)
>>> def callback(s):
...   return s*2
>>> Php.array_map(callback, arr1)
[2, 4, 6, 8, 10]
>>> def callback(s1, s2):
...   return {s1:s2}
>>> Php.array_map(callback, arr1, arr1)
[{1: 1}, {2: 2}, {3: 3}, {4: 4}, {5: 5}]

def array_merge(

arr1, arr2)

https://php.net/manual/en/function.array-merge.php

If the input arrays have the same string keys, the later value for that key will overwrite the previous one. If the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended. Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array.

def array_plus(

arr1, arr2)

https://php.net/manual/en/language.operators.array.php

The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, elements from the left-hand array will be used, & the matching elements from the right-hand array will be ignored.

array_merge() has slightly different behavior: (see above)

difference btw array_merge & array + array

>>> arr1 = array( (0,'1-0'),('a','1-a'),('b','1-b'),)
>>> arr2 = array( (0,'2-0'),(  1,'2-1'),('b','2-b'),('c','2-c'),)
>>> Php.array_plus(arr1, arr2)  # or arr1 + arr2
array(5) {[ 0 ]=> <'str'> 1-0, ['a']=> <'str'> 1-a, ['b']=> <'str'> 1-b,
          [ 1 ]=> <'str'> 2-1, ['c']=> <'str'> 2-c, }
>>> Php.array_merge(arr1, arr2)
array(6) {[ 0 ]=> <'str'> 1-0, ['a']=> <'str'> 1-a, ['b']=> <'str'> 2-b,
          [ 1 ]=> <'str'> 2-0, [ 2 ]=> <'str'> 2-1, ['c']=> <'str'> 2-c,}

def array_pop(

arr)

https://php.net/manual/function.array-pop.php

Pops and returns last value of the array, shortening the array by 1 element.

def array_push(

List, *args)

https://php.net/manual/function.array-push.php

Push one or more elements onto the end of array add elements to an array in PHP?

$cart = array(); $cart[] = 13; $cart[] = 14;
# same as:
$cart = array(); array_push($cart, 13); array_push($cart, 14);
# same as:
$cart = array(); array_push($cart, 13, 14);

if you're only pushing a single element every time (like in a loop) or a single element once, it's best to use the $cart[] = 13 method not only because it's less characters to do the same operation, but it also doesn't impose the performance overhead of a function call, which array_push() would.

def array_reverse(

arr, preserve_keys=False)

def array_shift(

arr)

https://php.net/manual/function.array-shift.php

Shifts the first value of the array off and returns it, shortening the array by one element and moving everything down. Integer indexes are reindexed to new sequence starting from 0.

wp> $arr = array(11, 22, 33)
=> array(3) { [0]=> int(11) [1]=> int(22) [2]=> int(33) }
wp> array_shift( $arr ) #out# => int(11)
wp> $arr
=> array(2) { [0]=> int(22) [1]=> int(33) }

wp> $Arr1 = array(11, 'a'=>99, 88=>888, 'b'=>'bb', 33)
wp> array_shift( $Arr1 )
=> int(11)
wp> $Arr1
=> array(4) { ["a"]  => int(99)
              [0]    => int(888)
              ["b"]  => string(2) "bb"
              [1]    => int(33)
            }

Python:

>>> Arr1 = array( 11, ('a',99), (88,888), ('b','bb'), 33 )
>>> Php.array_shift(Arr1)
11
>>> Arr1
array(4) { ['a']=><'int'>99
           [0]  =><'int'>888
           ['b']=><'str'>bb
           [1]  =><'int'>33 }

array.popitem(last=True) returns and removes a (key, value) pair. The pairs are returned in LIFO order if last is true or FIFO order if false.

>>> a = {1:'a', 2:'b'}
>>> a.pop(2)
'b'
>>> a
{1: 'a'}

def array_slice(

arr, offset, length=None, preserve_keys=False)

https://php.net/manual/function.array-slice.php

preserve_keys = False by default to reorder and reset the array indices. Set to TRUE to change this behaviour.

If length is given and is positive, the sequence will have that many elements in it. If length is given and is negative then the sequence will stop that many elements from the end of the array. If it is omitted, then the sequence will have everything from offset up until the end of the array.

def array_unique(

arr)

https://php.net/manual/function.array-unique.php

Takes an input array and returns a new array without duplicate values.

def array_walk(

arr, func, userdata=None)

https://php.net/manual/function.array-walk.php

bool array_walk(array &$array, callable $callback [, mixed $userdata=NULL])

Applies user-defined callback function to each element of the array array. array_walk() is not affected by the internal array pointer of array. It will walk through the entire array regardless of pointer position.

callback takes 2 params: 1) array param's value, 2) key/index If callback needs to be working with the actual values of the array, specify the first parameter of callback as a reference. Then, any changes made to those elements will be made in the original array itself. If the optional userdata parameter is supplied, it will be passed as the third parameter to the callback.

MUST CHANGE func to return modified val so arr[k] will be modified accordingly

php> $fruits = array("d"=>"lemon",  "a"=>"orange",
                     "b"=>"banana", "c"=>"apple"  );
php> function test_alter( &$item1, $key, $prefix ) {
         $item1 = "$prefix: $item1";
     }
php> array_walk($fruits, 'test_alter', 'fruit');
=> bool(true)
php> $fruits;
=> array(4) {
  ["d"]=> string(12) "fruit: lemon" , ["a"]=> string(13) "fruit: orange"
  ["b"]=> string(13) "fruit: banana", ["c"]=> string(12) "fruit: apple"
}

Python:

py> fruits = array( ("d","lemon"), ("a","orange"),
                    ("b","banana"),("c","apple"),  )
py> def test_alter(item1, key, prefix):
      return prefix +": " + item1
py> Php.array_walk(fruits, test_alter, 'fruit')
=> bool(true)
py> fruits
array(4) {
  ['d']=> <'str'> fruit: lemon , ['a']=> <'str'> fruit: orange,
  ['b']=> <'str'> fruit: banana, ['c']=> <'str'> fruit: apple ,
}

def ArrayAppend(

arr, var)

Appends var to array arr. In PHP, for example:

php> $B = array( 'a'=>'aa', 'b'=>'bb' );
php> $B[] = 'cc'; print_r($B);
Array( [a] => aa, [b] => bb, [0] => cc, )

def ArrayToObj(

arr)

https://php.net/manual/en/language.types.object.php

Convert array to object. Equivalent to php: (object) arr

If an object is converted to an object, it is not modified.

If a value of any other type is converted to an object, a new instance of the stdClass built-in class is created. If the value was NULL, the new instance will be empty. An array converts to an object with properties named by keys and corresponding values, with the exception of numeric keys which will be inaccessible unless iterated.

def ArrPy(

*args, **kwargs)

The following are ways to instantiate an array:

NewArr1 = ArrPy( [(1,11),(2,22)] )             # same as:
NewArr2 = array( _obj = ODict([(1,11),(2,22)]))
ArraySyntax = array(('a',11), 'zzz', (99,99), 22, 33, (2,22))
ODictSyntax = ArrPy([(11,111), (22,222)])

def arsort(

arr)

https://php.net/manual/function.arsort.php

Sort an array in reverse order and maintain index association.

>>> Php.arsort( array( ('banana',3), ('apple' ,4),
...                    ('pear'  ,1), ('orange',2), ))
array(4) { ['apple'] => <int> 4, ['banana']=> <int> 3, 
           ['orange']=> <int> 2, ['pear']  => <int> 1, }

>>> Php.arsort(array(("d","lemon"), ("a","orange"),
...                  ("b","banana"),("c","app")   ,))
>>> Php.asort( array(("d","lemon"), ("a","orange"),
...                  ("b","banana"),("c","app")   ,))

Php:

php> arsort(array("d"=>"lemon",  "a"=>"orange",
                  "b"=>"banana", "c"=>"apple", ));
php> foreach ($fruits as $key => $val) { echo "$key = $val\n"; }
a = orange, d = lemon, b = banana, c = apple

def asort(

arr)

https://php.net/manual/function.asort.php

Sorts an array and maintains index association.

>>> Php.asort( array( ('banana',3), ('apple' ,4),
...                   ('pear'  ,1), ('orange',2), ))
array(4) { ['pear']  => <int> 1, ['orange']=> <int> 2,
           ['banana']=> <int> 3, ['apple'] => <int> 4, }

def boolval(

var)

def call_user_func(

func, *args)

def call_user_func_array(

func, args)

def checkdate(

m, d, y)

def class_exists(

class_name, autoload=True, DefinedClasses=('wp_error',))

https://php.net/manual/en/function.class-exists.php

bool class_exists ( string $class_name [, bool $autoload = true ] )

  • class_name: The class name. The name is matched in a case-insensitive manner
  • autoload: Whether or not to call __autoload by default (disabled here)

Returns if the given class has been defined by using case-insensitive check: return class_name.lower() in DefinedClasses

DefinedClasses = ('wp_error',) allows users to add more defined classes.

def clone(

Obj, Class=None, DeepCopy=False)

def Cmp(

a, b)

Comparison function:

def Cmp(a, b):
  if a == b:
    return 0
  return -1 if a < b else 1

>>> A = array(('a',4),('b',8),('c',-1),('d',-9),
...           ('e',2),('f',5),('g', 3),('h',-4),)
>>> Php.uasort(A, Php.Cmp)

def cmp(

a, b)

https://docs.python.org/3.1/whatsnew/3.0.html

(a > b) - (a < b) as the equivalent for cmp(a, b)

def compact(

Locals, *keys)

https://php.net/manual/en/function.compact.php

Creates an array containing variables and their values

@params: pass locals() to Locals

Evil! Avoid using it! difficult to see array member gets set from a variable

php> compacted = compact( 'user_pass',...,'user_registered' )
php> compact('zz');
array(0){}         # Php gives no error when 'zz' not in Locals

php> $xjoin = 11; $join = 1;
php> compact( 'xjoin', array( 'fields', 'join', 'where', 'distinct',))
=> array(2) { ["xjoin"]=> int(11), ["join"]=> int(1) }

py> a  = 10; b = 2; Php.compact(locals(), 'a', 'b')
array(2) { ['a']=> <int> 10, ['b']=> <int> 2, }

def ConvertPhpPatternToPy(

pattern, flags=0)

https://php.net/regexp.reference.delimiters

Strip i at the end of pattern = '/^def/i'. Change to: re.IGNORECASE. Strips delimiters '/' at both ends of pattern.

Php '/^def/i' translated to Python '^def', re.IGNORECASE.

Delimiter can be any non-alphanumeric, non-backslash, non-whitespace char. Often used delimiters are forward slashes /, hash signs # and tildes ~.

def ConvertPhpStrFormatToPy(

Format)

Change a Format string by replacing '(%\d\$s|%d)' with '%s':

>>> Format = 'WordPress %1$s requires MySQL %d or higher'
>>> ConvertPhpStrFormatToPy(Format)  #equals to:
>>> re.sub('(%\d\$s|%d)', '%s', Format)
Out: 'WordPress %s requires MySQL %s or higher'

def ConvertPyMySqlColNamesToArray(

row)

Resolves difference between pymysql and Php.mysqli_fetch*:

Needs to convert from column name 'tt.term_id' to 'term_id'.

def ConvertPyMySqlColNamesToListOfArrays(

rows)

return [ ConvertPyMySqlColNamesToArray(row) for row in rows ]

def count(

List)

def current(

var)

Returns the value of the array element that's currently being pointed to by the internal pointer. It does not move the pointer in any way.

If the internal pointer points beyond the end of the elements list or the array is empty, current() returns FALSE.

def date_default_timezone_set(

TimeZone='US/Pacific')

https://php.net/manual/function.date-default-timezone-set.php

Python replacement for PHP's date_default_timezone_set.

def debug_backtrace(

provide_object=True)

https://php.net/manual/function.debug-backtrace.php

return list = [<FrameSummary file .../bin/ipython, line 11 in <module>>, ...]

def define(

Name, Value)

Tries to WpC.WB.define(Name, Value)

def defined(

Name)

Tries to check if WpC.WB.defined(Name)

def display(

o, space, num, key, typ, proret)

def dump(

o, space, num, key, typ, proret)

Used by var_dump() and var_export()

def echo(

Str)

Equivalent to print(Str)

def empty(

*Vars)

https://php.net/manual/function.empty.php

Determines whether a variable is empty. Returns true if the variable is an empty string, false, array(), NULL, "0", 0, or an unset variable.

Usage for local or global var:

>>> Php.empty({**locals(), **WB.Wj.__dict__}, attr)
>>> Php.empty({**locals(), **globals()     }, attr)

Given Wj.wpdb.blogid, will recursively find if nested objs or arrays are empty:

>>> empty(Wj, 'wpdb', 'blogid' ) #out# False
>>> empty(Wj, 'wpdb', 'blogidz') #out# True

def end(

var)

def error_log(

Str)

Equivalent to print(Str)

def escape_datetime(

obj, mapping=None)

def escape_string(

value, mapping=None)

escapes value without adding quote. Value should be unicode. Used by mysqli_real_escape_string()

Copied from pymysql.converters:

if not PY2: escape_string = _escape_unicode

def explode(

delimiter, Str, limit=None)

def extract(

Locals, d, Flag='EXTR_OVERWRITE')

https://php.net/manual/en/function.extract.php

Evil! Avoid using it! harder to determine where a variable was defined

raise NotImplementedError("Php.extract() is not supported since it's evil!")

@params: pass locals() to Locals

https://stackoverflow.com/questions/8028708/dynamically-set-local-variable

Modifying locals() is undefined! Outside a func when locals() and WB.Wj.__dict__ are the same it will work.

Inside a function is will usually not work. BAD Usage KeyError:

>>> Locals = Php.extract(locals(), group_key, 'EXTR_OVERWRITE' )
>>> for k in group_key.keys():
      locals()[k] = Locals[k]

Also bad in functions: var not defined!

>>> for k,v in d.items():
      # doesn't work in func: locals()[k] = v
      exec("{}= {}".format(k,
           v if isinstance(v,(int,float)) else repr(v)))

Translate to the following Python syntax instead:

>>> group = group_key['group']
>>> key   = group_key['key']

def file_exists(

filename)

def file_get_contents(

url)

def filesize(

file)

def floor(

var)

Returns the next lowest integer value by rounding down value if necessary:

>>> Php.floor(9.9)  #out: 9
>>> Php.floor(-9.9) #out: -10

def fsockopen(

hostname, port=-1, errno=None, errstr=None, timeout=60)

https://php.net/manual/en/function.fsockopen.php

(string hostname [, int port = -1 [, int &errno [, string &errstr
                 [, float timeout =
                    ini_get("default_socket_timeout") ]]]] )

Initiates a socket connection to the resource specified by hostname. use pyx.io.IsPortOpen instead.

def func_get_arg(

AllArgs, arg_num)

https://php.net/manual/en/function.func-get-arg.php

arg_num: arg offset. Function args are counted starting from zero.

Returns the specified argument from the AllArgs list, or FALSE on error.

def func_num_args(

AllArgs)

returns len(AllArgs)

def add_post_type_support( post_type, Feature, *OtherArgs ):
  AllArgs = post_type, Feature, *OtherArgs
  if Php.func_num_args(AllArgs) == 2:

def function_exists(

Func)

https://php.net/manual/function.function-exists.php

Returns if Func exists in this module or in dir(WpC.WB.Wj).

def get_class_vars(

Class)

def get_object_vars(

Obj)

https://php.net/manual/function.get-object-vars.php ReflectionObject vs. cast to array vs. get_object_vars for retrieving public vars

Returns an array that contains the accessible non-static properties of a given object that are visible from the calling scope. (e.g. it may or may not return protected or private variable). None will return if a property has not been assigned a value

Casting to array returns all properties, including private ones.

def gettype(

var)

Returns type(var)

def html_escape(

text)

Escaping Html

Produce entities within text: escape quotes and apostrophes as well.

def htmlentities(

text, Quote='ENT_QUOTES', Charset='UTF-8')

https://php.net/manual/function.htmlentities.php

Translate all HTML char entities! Available quote_style constants:

Constant Name Description
ENT_COMPAT    convert double-quotes and leave single-quotes alone.
ENT_QUOTES    convert both double and single quotes.
ENT_NOQUOTES  leave both double and single quotes unconverted.

Charset: UTF-8 ASCII compatible multi-byte 8-bit Unicode.

def htmlspecialchars(

text, Quote='ENT_QUOTES', Charset='UTF-8', double_encode=True)

https://php.net/manual/function.htmlspecialchars.php

For all HTML char entities to be translated, use htmlentities() instead. Only translate HTML char entities

& (ampersand) becomes '&amp;'
" (double quote) becomes '&quot;' when ENT_NOQUOTES is not set.
' (single quote) becomes '&#039;' only when ENT_QUOTES is set.
< (less than) becomes '&lt;'
> (greater than) becomes '&gt;'

Charset: UTF-8 ASCII compatible multi-byte 8-bit Unicode. When double_encode is turned off PHP will not encode existing html entities, the default is to convert everything.

def htmlspecialchars1(

text)

php htmlspecialchars in py escape quotes and apostrophes as well.

def in_array(

needle, haystack, Strict=False)

https://php.net/manual/function.in-array.php

Searches haystack (an array) for needle using loose comparison. If the third parameter strict is set to TRUE, in_array() also checks the types of the needle in the haystack.

>>> Arr  = array( (0,3), (1,2), ('',3), ('a',333) )
>>> Php.in_array(1, Arr)
False
>>> Php.in_array(333, Arr)
True

def ini_get(

Var)

https://php.net/manual/function.ini-get.php

Returns the value of the configuration option on success.

def intval(

var, base=None)

https://php.net/manual/en/function.intval.php

Returns the integer value of var, using the specified base for the conversion (the default is base 10).

php> intval('11a11')  => int(11)   #TODO
php> intval('a11a11') => int(0)
py>  int('') => ValueError: invalid literal for int() with base 10: ''
php> (int)'' => int(0)

def is_array(

var, AllowIterTypes=True)

https://php.net/manual/en/function.is-array.php

Returns whether var is an array.

def is_bool(

var)

def is_float(

var)

def is_int(

var)

lambda x: isinstance(x, int)

def is_null(

var)

def is_object(

val, ExcludeClass=False)

def is_scalar(

var)

https://php.net/manual/en/function.is-scalar.php

Returns if var is a one of ScalarTypes = (int, float, str, bool).

Notes: Types NULL, array, object and resource are not scalar !!!

def is_string(

var)

def isset(

*Vars)

https://php.net/manual/en/types.comparisons.php

Determine if a variable is set and is not NULL. Returns true only when the variable is not null.

wp> isset($wpdb->zzz);   #=> bool(false)
wp> $wpdb->zzz = null;   #=> NULL
wp> isset($wpdb->zzz);   #=> bool(false)
wp> isset($Unknown[1])   #=> bool(false)

So isset($this->$attr) can't translate to py as: hasattr(var, attr) Usage for local or global var:

Php.isset({**locals(), **WB.Wj.__dict__}, attr)

WARNING!! Must translate from PHP to py as:

php> isset($a, $b)
py>  Php.isset(locals(),'a') and Php.isset(locals(),'b')

The following can recursively find if nested objs or arrays are empty:

>>> wpdb.query("select count(*) from wp_users")
>>> isset(wpdb, 'last_result', 0, "count(*)")
True
>>> empty(wpdb, 'last_result', 0, "count(*)")
False

same as Php:

php> isset( $wpdb->last_result[0]->{'count(*)'} )
=> bool(true)
php> empty( $wpdb->last_result[0]->{'count(*)'} )
=> bool(false)

php> if ( isset($error) )
py>  if Php.isset(locals(), 'error'):

php> if ( ! isset( self::$back_compat_keys ) ) {
          self::$back_compat_keys = array(
py>  if not Php.isset(self, back_compat_keys):
       setattr(self, back_compat_keys, array(

php> if ( isset( self::$back_compat_keys[ $key ] ) )
          $key = self::$back_compat_keys[ $key ];
py>  if Php.isset( getattr(self, back_compat_keys), key ):
       key = getattr(self, back_compat_keys)[ key ]

php> $this->data->$key = $value;
py>  setattr(this.data, key, value)
php> if ( isset( $this->data->$key ) ) {
          unset( $this->data->$key );
py>  if Php.isset( self.data, key ):
       Php.unset( this.data, key ) # delattr( this.data, key )

php> = isset( clauses[ 'fields' ] ) ? clauses[ 'fields' ] : ''
py>  = clauses.get('fields'  , '')  # a better translation to py

def key(

arr)

Returns the index element of the current array position.

def ksort(

arr)

Improve ksort_to_list. Returns a new array.

def ksort_to_list(

arr)

https://php.net/manual/function.ksort.php

Had we used a Python dictionary as an associative array, we will not be able to "modify the order" of the dictionary like you can in PHP, since py dict is unordered.

Since we use py OrderedDict for the array arr, we return a new list of the (key, value) pairs of the array sorted according to arr.keys().

def levenshtein(

s1, s2)

def ltrim(

Str, charlist=' \t\n\r\x00\x0b')

https://php.net/manual/function.ltrim.php

Strip whitespace (or other characters) from the beginning of a string.

def Max(

*args)

https://php.net/manual/en/function.max.php

Max() here emulates PHP max(). It's different from py builtin max()!! Values of different types will be compared using the standard comparison rules. For instance, a non-numeric string will be compared to an integer as though it were 0, but multiple non-numeric string values will be compared alphanumerically. The actual value returned will be of the original type with no conversion applied.

  • params: MappingTypes = (dict, ODict, array) or SeqSetTypes.
  • returns: max of MappingTypes.values() or SeqSetTypes. Otherwise returns None, and print PHP Warning message.

def mb_check_encoding(

Str, Encoding='ASCII')

def mb_internal_encoding(

Encoding, MbIntEncoding=['UTF-8'])

def mb_strlen(

Str, encoding='utf-8')

Begins with Py3, all strings are unicode objects. Remove .decode('utf-8')

def mb_strtolower(

Str, Encoding)

def mb_strtoupper(

Str, Encoding)

def mb_substr(

*args, **kwargs)

def md5(

Str, raw_output=False)

Calculates md5 hash of a string. Emulate:

php> md5( 1   );  # same as:
php> md5('1'  );
php> md5( 2.2 );  # same as:
php> md5('2.2');

py> md5(b'hello world')  # same as:
py> md5( 'hello world')

def microtime(

get_as_float=False)

https://php.net/manual/function.microtime.php

Returns current Unix timestamp with microseconds.

def Min(

*args)

https://php.net/manual/en/function.min.php

Min() here emulates PHP min(). It's different from py builtin min() !!

Values of different types will be compared using the standard comparison rules. For instance, a non-numeric string will be compared to an integer as though it were 0, but multiple non-numeric string values will be compared alphanumerically. The actual value returned will be of the original type with no conversion applied.

  • params: MappingTypes = (dict, ODict, array), or SeqSetTypes.
  • returns: min of MappingTypes.values() or SeqSetTypes. Otherwise returns None, and print PHP Warning message.

def multiple_replace(

dic, text)

Perform multiple replacements in one step. For example:

>>> dic = { "Larry Wall" : "Guido van Rossum",
...         "creator" : "Benevolent Dictator for Life",
...         "Perl" : "Python",
...       }
>>> print(multiple_replace(dic, some_text))

def mysql_affected_rows(

dbh)

def mysql_close(

dbh)

def mysql_fetch_assoc(

dbh)

def mysql_fetch_field(

dbh)

def mysql_fetch_row(

dbh)

def mysql_get_client_info(

dbh=None)

return mysqlnd

def mysql_get_server_info(

dbh)

Warning: mysql_get_server_info() expects parameter 1 to be resource, object given... eval()'d code on line 1

=> NULL

return None

def mysql_insert_id(

dbh)

def mysql_num_fields(

dbh)

def mysql_ping(

dbh, reconnect=False)

def mysql_query(

query, dbh)

https://php.net/manual/function.mysql-query.php

return mysqli_query(dbh, query)

def mysql_real_escape_string(

Str, dbh)

def mysql_result(

dbh, N=0)

Orig params: mysql_result(result, 0), replace with (dbh, 0)

def mysql_set_charset(

charset, dbh)

def mysqli_affected_rows(

dbh)

def mysqli_close(

dbh)

def mysqli_fetch_array(

dbh, result_type='MYSQL_BOTH')

https://php.net/manual/en/function.mysql-fetch-array.php

Orig params: mysqli_fetch_array(result), replace with (dbh)

Returns an array of strings that corresponds to the fetched row, or FALSE if no more rows. The type of returned array depends on how result_type is defined. By using MYSQL_BOTH (default), you'll get an array with both associative and number indices =ODict for py. Using MYSQL_ASSOC, you only get associative indices (as mysql_fetch_assoc() works), using MYSQL_NUM, you only get number indices (as mysql_fetch_row() works).

wp> global $wpdb ; $dbh = $wpdb->dbh
wp> $res = mysqli_query($dbh, 'select * from wp_users limit 3')
=> object(mysqli_result)#864 (5) {
        ["current_field"]=> 0, ["field_count"]=> 12,
        ["lengths"]=> NULL, ["num_rows"]=> 2, ["type"]=> 0, }
wp> $modes_array = mysqli_fetch_array( $res )  #default to: 'MYSQL_BOTH'
=> array(24) { [0]    => str(1) "4"    ,
               ["ID"] => str(1) "4"    ,
               [1]    => str(9) "zq...",
               ["user_login"]=> str(9) "zq...", ...... }
wp> $a1 = mysqli_fetch_array( $res, MYSQL_NUM )
=> array(12) { [0]=> str(1) "5"
               [1]=> str(7) "aksylin" }
wp> $a2 = mysqli_fetch_array( $res, MYSQL_ASSOC )
=> array(12) { ["ID"]=> str(1) "6"
               ["user_login"]=> str(9) "anusnu888",... }

def mysqli_fetch_assoc(

dbh)

Orig params: mysqli_fetch_assoc(result), replace with (dbh)

def mysqli_fetch_field(

dbh, ColNum)

Orig params: mysqli_fetch_row(result), replace with (dbh, ColNum)

def mysqli_fetch_object(

dbh, cls=<class 'pyx.php.stdClass'>, params={})

In Php, mysqli_fetch_object returns row by row.

def mysqli_fetch_row(

dbh)

Orig params: mysqli_fetch_row(result), replace with (dbh).

Gets a result row as an enumerated array.

def mysqli_free_result(

dbh)

https://php.net/manual/en/mysqli-result.free.php

Frees the memory associated with the result. should always free result with mysqli_free_result(), when your result object is not needed anymore

Orig params: mysqli_free_result(result), replace with (dbh).

def mysqli_get_client_info(

dbh=None)

return mysqlnd

def mysqli_get_server_info(

dbh)

return "5.5.5-10.1.19-MariaDB-1~xenial"

wp> mysqli_get_server_info ($wpdb->dbh);
=> string(30) "5.5.5-10.1.19-MariaDB-1~xenial"

def mysqli_insert_id(

dbh)

def mysqli_more_results(

dbh)

https://php.net/manual/en/mysqli.more-results.php

Check if there are any more query results from a multi query.

Returns TRUE if one or more result sets are available from a previous call to mysqli_multi_query(), otherwise FALSE.

def mysqli_next_result(

dbh)

https://php.net/manual/en/mysqli.next-result.php

mysqli_next_result — Prepare next result from multi_query Prepares next result set from a previous call to mysqli_multi_query() which can be retrieved by mysqli_store_result() or mysqli_use_result(). Returns TRUE on success or FALSE on failure.

def mysqli_num_fields(

dbh)

Orig params: mysqli_num_fields(result), replace with (dbh).

Gets the number of fields in a result.

def mysqli_ping(

dbh, reconnect=False)

def mysqli_query(

dbh, query, Tries=3, Exit=<built-in function exit>)

Try to execute SQL using cursor().execute() method for Tries # of times. After Tries # of times,

  :::python
  def mysqli_query(dbh, query, Tries=3, Exit=sys.exit):
    for Try in range(Tries):
      V('Try to execute query:', Try, query)
      try:
        return dbh.execute(query)
      except:
        xFn.PrintError(sys.exc_info(), Try)
      time.sleep(Try**2)

    Exit("

Cannot execute Sql after {} Tries! ".format(Tries)) return False

Need to dbconn.close() later since our translation to Python does not use context manager as below:

  with dbconn.cursor() as cur:

def mysqli_real_escape_string(

dbh, Str)

https://php.net/manual/en/mysqli.real-escape-string.php

Escapes special characters in a string for use in an SQL statement, taking into account the current charset of the connection.

wp> mysqli_real_escape_string( $wpdb->dbh, 123 );
=> string(3) "123"
wp> mysqli_real_escape_string( $wpdb->dbh, '123' );
=> string(3) "123"
wp> sprintf('%d', '123');
=> string(3) "123"
wp> sprintf('%d', 'abc');
=> string(1) "0"

def mysqli_set_charset(

dbh, charset)

https://php.net/manual/en/mysqli.set-charset.php

Returns TRUE on success or FALSE on failure.

def Next(

var)

def NextLargestIntKey(

arr)

Returns next numeric key in an array to increment its key, if numeric keys are found. Otherwise, returns next available num key = 0.

def number_format(

num, places=0)

https://php.net/manual/function.number-format.php

Formats a number with grouped thousands.

>>> import locale
>>> locale.setlocale(locale.LC_NUMERIC, '')
>>> print(number_format(12345.6789, 2))
12,345.68

def Object(

arr)

https://php.net/manual/en/language.types.object.php

Convert array to object. Equivalent to php: (object) arr

If an object is converted to an object, it is not modified.

If a value of any other type is converted to an object, a new instance of the stdClass built-in class is created. If the value was NULL, the new instance will be empty. An array converts to an object with properties named by keys and corresponding values, with the exception of numeric keys which will be inaccessible unless iterated.

def ObjToArrPy(

Obj, Strict=True)

Converts stdClass() object to array

def parse_url(

Url, component=None)

https://php.net/manual/en/function.parse-url.php

parse_url() parses a URL and returns an associative array containing any of the various components of the URL that are present. The values of the array elements are not URL decoded.

def ParseFlagFromPattern(

pattern, flags=0)

re.I= 2, re.L=4, re.M=8, re.S=16, re.I|re.S=18, re.M|re.S|re.I=26

def phpversion(

)

return '5.6.28'

def preg_match(

pattern, subject, flags=0)

https://php.net/manual/en/function.preg-match.php

Returns 1 if pattern matches given subject, 0 if not, or FALSE if error.

def preg_match_Result(

pattern, subject, flags=0)

https://php.net/manual/en/function.preg-match.php

Returns 1 if pattern matches given subject, 0 if not, or FALSE if error.

php> preg_match('/(foo)(bar)(baz)/', 'foobarbaz', $matches);
=> int(1)
php> $matches;
=> array(4) {
  [0]=> string(9) "foobarbaz"
  [1]=> string(3) "foo"
  [2]=> string(3) "bar"
  [3]=> string(3) "baz" }
php> preg_match('/(fooz)(barz)(bazz)/', 'foobarbaz', $matches);
=> int(0)
php> $matches;
=> array(0) { }

def preg_match_tuple(

pattern, subject, flags=0)

Returns a tuple containing all the subgroups of the match, from 1 up to however many groups are in the pattern.

def preg_quote(

Str, delimiter=None)

https://php.net/manual/en/function.preg-quote.php

preg_quote() takes Str and puts a \ in front of every char that is part of regex syntax. If delimiter is specified, it will be escaped.

The special regex chars are: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -

Note: / is not a special regular expression character.

php> $keywords = preg_quote('$40 for a g3/400', '/');
php> echo $keywords;
=>  \$40 for a g3\/400  # same as py output below

Why re.escape escapes space

>>> re.escape(       '$40 for a g3/400')
'\$40\ for\ a\ g3\/400'
>>> print(re.escape( '$40 for a g3/400'))
'\$40\ for\ a\ g3\/400'
>>> print(Php.preg_quote('$40 for a g3/400','/'))
'\$40 for a g3\/400'

def preg_replace(

pattern, replacement, subject, limit=-1, flags=0)

https://php.net/manual/en/function.preg-replace.php

limit: The maximum possible replacements for each pattern in each subject string. Defaults to -1 (no limit).

Returns an array if the subject parameter is an array, or a str otherwise.

If matches are found, the new subject will be returned, otherwise subject will be returned unchanged or None if an error occurred.

php: replacement= '$1'
py:  r'' . r= raw str so no need to escape ''

def prev(

var)

def RecursiveCopyODict(

od, Class=None, DeepCopy=False)

def reset(

var)

Rewinds array pointer to the first element, and returns value of the first element.

def rtrim(

Str, charlist=' \t\n\r\x00\x0b')

https://php.net/manual/function.rtrim.php

Strip whitespace (or other characters) from the end of a string.

def shuffle(

arr)

https://php.net/manual/function.shuffle.php

Shuffles (randomizes the order of the elements in) an array.

def so(

a, b)

return strcmp(a['id'], b['id'])

def sprintf(

Format, *args)

https://php.net/manual/function.sprintf.php

Returns a string produced according to the formatting string format.

def sprintf_StringIO(

Format, *args)

def static_vars(

**kwargs)

[py eq of static vars inside function](stackoverflow.com/questions/279561/

def str_replace(

Search, Replace, Subject)

https://php.net/manual/function.str-replace.php

If search and replace are arrays, str_replace() takes a value from each array and uses them to search and replace on subject. If replace has fewer values than search, an empty string is used for the rest of replacement values. If search is an array and replace is a string, this replacement string is used for every value of search. The converse would not make sense, though.

>>> vowels = ("a", "e", "i", "o", "u"); uv = ("A", "E", "I", "O", "U")
>>> Php.str_replace(vowels, uv, "Hello World of PHP")
'HEllO WOrld Of PHP'

def str_split(

string, split_length)

https://php.net/manual/function.str-split.php

DEPRECATED in PHP 5.3. Use explode() instead that works with delimiter char. Should use preg_split() to split str with regex.

def strcmp(

Str1, Str2)

http://php.net/manual/en/function.strcmp.php

Both params must be strings, the result is otherwise extremely unpredictable returns -1 ou 1 if two strings are not identical, and 0 when they are, except when comparing a str and an empty str "", it returns the str length.

def strip_tags(

HTML)

https://php.net/manual/en/function.strip-tags.php

If lxml is install, it will try to import and use it to strip all HTML tags. This is the BEST, most-reliable and fastest method to strip HTML tags!!

If lxml is not installed, it will simpliy use regex:

ReCompiled = re.compile(r'(<!--.*?-->|<[^>]*>)')
return ReCompiled.sub('', HTML)

def stripos(

haystack, needle, offset=0)

https://php.net/manual/function.stripos.php

Find numeric position of the 1st occurrence of needle in the haystack str. Unlike the strpos(), stripos() is case-insensitive.

php> stripos(haystack, needle) !== FALSE
py>  needle.lower() in haystack.lower()

def stripslashes(

Str)

def strlen(

Str)

return len(Str)

def strpos(

haystack, needle, offset=0)

https://php.net/manual/function.strpos.php

Returns numeric position of 1st occurrence of needle in the haystack str.

php> strpos(haystack, needle) !== FALSE    # is not False in py
py>  needle in haystack

def strrev(

Str)

def strstr(

haystack, needle, before_needle=False)

def strtolower(

Str)

wp> strtolower( null ); #out=> string(0) ""

def strtotime(

Str, format_string='%Y-%m-%d %H:%M:%S')

https://php.net/manual/function.strtotime.php

format_string can also be: "%m/%d/%Y %H:%M" Code below is not ideal. Can only use on date strings and cannot "+1 hour" and have to specify the string format:

def strtotime(Str, format_string = '%Y-%m-%d %H:%M:%S'):
  tuple = time.strptime(Str, format_string)
  return int(time.mktime(tuple))

def strtoupper(

Str)

wp> strtoupper( null ); #out=> string(0) ""

def substr(

Str, start=0, length=None)

https://php.net/manual/function.substr.php

Returns the portion of string specified by the start and length params.

def switch(

x, Dict, Default='')

PHP switch() can be translated to Python by using the dictionary get(key[, default]) method:

def switch(x, Dict, Default=''):
  ' Returns Default if x not found in Dict.keys() '
  return Dict.get(x, Default)
>>> Dict = { 'a': 1, 'b': 2, }
>>> switch('a', Dict, 'D')

However, it's still best to translate to if, elif, elif,... , else.

def trim(

Str, charlist=' \t\n\r\x00\x0b')

https://php.net/manual/en/function.trim.php

Returns a string with whitespace stripped from the beginning and end of str. Without the second parameter, trim() will strip these characters:

" "    (ASCII 32 (0x20)), an ordinary space.
"\t"   (ASCII  9 (0x09)), a tab.
"\n"   (ASCII 10 (0x0A)), a new line (line feed).
"\r"   (ASCII 13 (0x0D)), a carriage return.
"\0"   (ASCII  0 (0x00)), the NUL-byte.
"\x0B" (ASCII 11 (0x0B)), a vertical tab.

https://docs.python.org/3.6/library/stdtypes.html#str.strip

def uasort(

arr, keyfunc)

https://php.net/manual/en/function.uasort.php

Sort an array with user-defined comparison func & maintain index association array indices maintain their correlation with the array elements they are associated with, using a user-defined comparison function.

Difference between uasort() and usort(), the missing example ...

php> $arr= array( 10=>array('id'=>'dix', 'aa'=>'1010'),
                 100=>array('id'=>'cent','aa'=>'100100'),
                   2=>array('id'=>'deux','aa'=>'22'),
                   7=>array('id'=>'sept','aa'=>'77'));
# sort id
php> function so($a, $b) { return (strcmp ($a['id'],$b['id'])); }
php> uasort($arr, 'so')
=> bool(true)
php> $arr
=> array(4) {
  [100]=> array(2) {
    ["id"]=> string(4) "cent"
    ["aa"]=> string(6) "100100" }
  [2]=> array(2) {
    ["id"]=> string(4) "deux"
    ["aa"]=> string(2) "22" }
  [10]=> array(2) {
    ["id"]=> string(3) "dix"
    ["aa"]=> string(4) "1010" }
  [7]=> array(2) {
    ["id"]=> string(4) "sept"
    ["aa"]=> string(2) "77" }
}
php> usort($arr, 'so')
=> bool(true)
php> $arr
=> array(4) {
  [0]=> array(2) {
    ["id"]=> string(4) "cent"
    ["aa"]=> string(6) "100100" }
  [1]=> array(2) {
    ["id"]=> string(4) "deux"
    ["aa"]=> string(2) "22" }
  [2]=> array(2) {
    ["id"]=> string(3) "dix"
    ["aa"]=> string(4) "1010" }
  [3]=> array(2) {
    ["id"]=> string(4) "sept"
    ["aa"]=> string(2) "77" }
}

Python:

py> arr = array(( 10,array(('id','dix' ),('aa','1010'  ))),
                (100,array(('id','cent'),('aa','100100'))),
                (  2,array(('id','deux'),('aa','22'    ))),
                (  7,array(('id','sept'),('aa','77'    ))),)
py> Php.usort( arr, Php.so)
py> Php.uasort(arr, Php.so)

def ucfirst(

Str)

https://php.net/manual/function.ucfirst.php

Makes a string's first character uppercase.

def ucwords(

source)

https://php.net/manual/function.ucwords.php

Uppercase the first character of each word in a string.

>>> ucwords("Michael o'keefe")
"Michael O'keefe"

def ucwords_py(

Str)

def unset(

var, attr=None)

https://php.net/manual/en/function.unset.php Destroys var, or var.attr:

php> unset( $this->data->$key );
py>  delattr( this.data, key )
php> unset( self::$back_compat_keys[ $key ] );
py>  Php.unset( getattr(self, back_compat_keys)[ key ] )

Since Php doesn't raise error for deleting absent key or if attr doesn't exist, so py error exception is to: print("Cannot unset: var={}, attr={}".

def urldecode(

Str)

https://php.net/manual/function.urldecode.php

Url decode UTF-8 in Python

php > var_dump( urldecode('are=green+and+red') );
string(17) "are=green and red"

def urlencode(

Str)

urlencode different from WiF.utf8_uri_encode:

php> utf8_uri_encode( "EFI收购Cr" );
=> string(31) "EFI%e6%94%b6%e8%b4%adCr"
php> urlencode( "EFI收购Cr" );
=> string(23) "EFI%E6%94%B6%E8%B4%ADCr"

def UrlEncodedHexToLowercase(

Str)

'%2FEl+Ni%C3%B1o%2F' => '/El+Ni%c3%b1o/'

def usort(

arr, keyfunc)

https://php.net/manual/en/function.usort.php

Sorts an array by its values using a user-supplied comparison function.

If 2 members compare as equal, their relative order in the sorted array is undefined. This func assigns new keys to elements in array. It removes any existing keys that may have been assigned, rather than reordering the keys.

See Difference between uasort() and usort(), the missing example ...

def usort1(

arr, keyfunc)

same as usort()

def usort2(

arr, keyfunc)

same as usort()

def V(

*args)

def var_dump(

*obs)

Equivalent to PHP's var_dump(). Displays type, value etc structured info of py object, list, tuple, dict, etc.

def var_export(

*obs)

Same as var_dump(), but returns output as a string.

def version_compare(

v1, v2, op=None)

def vsprintf(

Format, args)

https://php.net/manual/en/function.vsprintf.php

Operates as sprintf() but accepts an array of arguments, rather than a variable number of arguments.

Module variables

var AllDataTypes

var CASE_LOWER

var CASE_UPPER

var CharMask

CharMask = " \t\n\r\0\x0B"

var FreeRegLicenseArraysLimit

var IterTypes

var MappingTypes

var mysqlnd

= "mysqlnd 5.0.11-dev - 20120503 - $Id: 76b08b24596e12d4553bd41fc93cccd5bac2fe7a $"

var NumericTypes

= (int, float, complex,)

var PHP_URL_FRAGMENT

var PHP_URL_HOST

var PHP_URL_PASS

var PHP_URL_PATH

var PHP_URL_PORT

var PHP_URL_QUERY

var PHP_URL_SCHEME

https://php.net/manual/en/function.parse-url.php

Defines only available in PHP 5, created for PHP4.

PHP_URL_SCHEME  = 1
PHP_URL_PORT    = 3
PHP_URL_USER    = 4
PHP_URL_PASS    = 5
PHP_URL_PATH    = 6
PHP_URL_QUERY   = 7
PHP_URL_FRAGMENT= 8

var PHP_URL_USER

var PHP_VERSION

= '5.6.31-4+ubuntu16.04.1+deb.sury.org+4'

var ScalarTypes

= (bool, str, bytes, int, float, complex,)

var SeqSetTypes

= (list, tuple, range, set, frozenset,)

var SeqTypes

= (list, tuple, range,)

var SetTypes

= (set, frozenset,)

var TAB_SIZE

var UnRegLicenseArraysLimit

var whitespace