I am using Visual Studio Code(VS Code), it can display the annotation of functios.
I am try to improve write a PHPDoc standard.
Can any suggestions to me? Thank you.
Here have 3 functions, but they are not the focal point .
I just want to know how to write a PHPDoc standard describe the function 2 and simulation overload function 3.
Ref:
https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md#54-examples
<?php
// Function 1:
/**
* Check if A is equal to B.(Just a sample note, not important)
*
* #param string A
* #param string B
*
* #return bool
*/
function checkAandB_1($a, $b){
if($a === $b)
return true;
return false;
}
// Function 2:
/**
* Check if A is equal to B.(Just a sample note, not important)
*
* #param string Input x,y (<=here, I need to known how to write a right note to describe this function can support input a string combin x and y with a comma in one line)
*
* #return bool
*/
function checkAandB_2($str){
if( substr_count($str, ",") === 1 ) {
$strArr = explode(",",$str);
if($strArr[0] === $strArr[1])
return true;
}
return false;
}
// Function 3: Simulation a overload function
/**
* Check if A is equal to B.(Just a sample note, not important)
*
* #param string (What's the best annotation to describe this function?)
*
* #return bool
*/
function checkAandB_overload($str, $b = null){
if(isset($b) && $str === $b){
return true;
}elseif( substr_count($str, ",") === 1 ) {
$strArr = explode(",",$str);
if($strArr[0] === $strArr[1])
return true;
}
return false;
}
var_dump(checkAandB_1("1","2")); // false
var_dump(checkAandB_1("2","2")); // true
var_dump(checkAandB_2("1,2")); // false
var_dump(checkAandB_2("2,2")); // true
var_dump(checkAandB_overload("1","2")); // false
var_dump(checkAandB_overload("2","2")); // true
var_dump(checkAandB_overload("1,2")); // false
var_dump(checkAandB_overload("2,2")); // true
Related
I'm using PHP and curl with json to interact with my geth server.
I'm able to do all I want except one thing: checking if user's inputted address is valid according to ethereum wallet format.
I saw a javascript function here, but I'm mostly using PHP, I'm not into JS at all.
Any ideas how to validate ethereum addresses in PHP?
Here's a PHP implementation for Ethereum address validation against the EIP 55 specification. For details of how it works, please go through the comments.
<?php
use kornrunner\Keccak; // composer require greensea/keccak
class EthereumValidator
{
public function isAddress(string $address): bool
{
// See: https://github.com/ethereum/web3.js/blob/7935e5f/lib/utils/utils.js#L415
if ($this->matchesPattern($address)) {
return $this->isAllSameCaps($address) ?: $this->isValidChecksum($address);
}
return false;
}
protected function matchesPattern(string $address): int
{
return preg_match('/^(0x)?[0-9a-f]{40}$/i', $address);
}
protected function isAllSameCaps(string $address): bool
{
return preg_match('/^(0x)?[0-9a-f]{40}$/', $address) || preg_match('/^(0x)?[0-9A-F]{40}$/', $address);
}
protected function isValidChecksum($address)
{
$address = str_replace('0x', '', $address);
$hash = Keccak::hash(strtolower($address), 256);
// See: https://github.com/web3j/web3j/pull/134/files#diff-db8702981afff54d3de6a913f13b7be4R42
for ($i = 0; $i < 40; $i++ ) {
if (ctype_alpha($address{$i})) {
// Each uppercase letter should correlate with a first bit of 1 in the hash char with the same index,
// and each lowercase letter with a 0 bit.
$charInt = intval($hash{$i}, 16);
if ((ctype_upper($address{$i}) && $charInt <= 7) || (ctype_lower($address{$i}) && $charInt > 7)) {
return false;
}
}
}
return true;
}
}
Dependencies
To validate checksum addresses, we need a keccak-256 implementation in place which is not supported by the built-in hash() function. You need to require the greensea/keccak composer package as a dependency.
Kudos to #WebSpanner for pointing out the issue with SHA3 hashing.
Basically, you can convert the javascript entirely to PHP.
Here i have been able to convert and test the code for validating an ethereum address in PHP.
/**
* Checks if the given string is an address
*
* #method isAddress
* #param {String} $address the given HEX adress
* #return {Boolean}
*/
function isAddress($address) {
if (!preg_match('/^(0x)?[0-9a-f]{40}$/i',$address)) {
// check if it has the basic requirements of an address
return false;
} elseif (!preg_match('/^(0x)?[0-9a-f]{40}$/',$address) || preg_match('/^(0x)?[0-9A-F]{40}$/',$address)) {
// If it's all small caps or all all caps, return true
return true;
} else {
// Otherwise check each case
return isChecksumAddress($address);
}
}
/**
* Checks if the given string is a checksummed address
*
* #method isChecksumAddress
* #param {String} $address the given HEX adress
* #return {Boolean}
*/
function isChecksumAddress($address) {
// Check each case
$address = str_replace('0x','',$address);
$addressHash = hash('sha3',strtolower($address));
$addressArray=str_split($address);
$addressHashArray=str_split($addressHash);
for($i = 0; $i < 40; $i++ ) {
// the nth letter should be uppercase if the nth digit of casemap is 1
if ((intval($addressHashArray[$i], 16) > 7 && strtoupper($addressArray[$i]) !== $addressArray[$i]) || (intval($addressHashArray[$i], 16) <= 7 && strtolower($addressArray[$i]) !== $addressArray[$i])) {
return false;
}
}
return true;
}
Meanwhile, for someone looking for a very simple regular expression for checking ethereum address validity (e.g to use is as a pattern attribute of an HTML field), this regular expression may suffice.
^(0x)?[0-9a-fA-F]{40}$
Can i get the effect of JSON_NUMERIC_CHECK without JSON?
i.e. Recrusive replacement of numeric strings to ints or floats.
Example with JSON_NUMERIC_CHECK:
<?php
// some input from somewhre
$data = explode(',', 'abc,7,3.14');
echo "Before:"; var_dump($data);
$data = json_decode(json_encode($data, JSON_NUMERIC_CHECK), TRUE);
echo "After:"; var_dump($data);
But I geuss converting to json and back is slow, is there some other way to get the same result?
You can loop over your strings and cast any numeric value to int or float using the following code:
/**
* Normalize an object, array or string by casting all
* numeric strings it contains to numeric values.
*
* #param array|object|string $data
* #return mixed
*/
function normalize($data) {
if (is_array($data))
return array_map('normalize', $data);
if (is_object($data))
return (object) normalize(get_object_vars($data));
return is_numeric($data) ? $data + 0 : $data;
}
$data = "15,2.35,foo";
$data = normalize(explode(',', $data));
// => [15, 2.35, 'foo']
Hope this helps :)
More efficient way
/**
* Normalize an string or object by casting all
* numeric strings it contains to numeric values.
* Note that it changes the variable directly
* instead of returning a copy.
*
* #param object|string $data
* #return void
*/
function normalizeItem(&$data) {
if (is_object($data)) {
$data = get_object_vars($data);
normalize($data);
$data = (object) $data;
} else {
$data = is_numeric($data) ? $data + 0 : $data;
}
}
/**
* Applies normalizeItem to an array recursively.
*
* #param array &$list
* #return bool
*/
function normalize(&$list) {
return array_walk_recursive($list, 'normalizeItem');
}
You can use array_map() with a callback.
$data = explode(',', 'abc,7,3.14');
$re = array_map(function(&$a) {
return ctype_digit($a) ? intval($a) : $a;
}, $data);
var_dump($re);
https://eval.in/715641
What is the easiest way to check if a string contains a valid float?
For example
is_string_float("1") = true
is_string_float("1.234") = true
is_string_float("1.2e3") = true
is_string_float("1b2") = false
is_string_float("aldhjsfb") = false
The easiest way would be to use built in function is_float(). To test if a variable is a number or a numeric string you must use is_numeric().
If you really want to know if a string contains a float and ONLY a float you cannot use is_float() (wrong type) or is_numeric() (returns true for a string like "1" too) only. I'd use
<?php
function foo(string $string) : bool {
return is_numeric($string) && strpos($string, '.') !== false;
}
?>
instead.
maybe you can use a couple of functions
out of the box
function is_string_float($string) {
if(is_numeric($string)) {
$val = $string+0;
return is_float($val);
}
return false;
}
This can easily be achieved by double casting.
/**
* #param string $text
* #return bool
*/
function is_string_float(string $text): bool
{
return $text === (string) (float) $text;
}
I wanted to make function with this possible argument:s
leFunction ((string) $type,(string) $data) , this was simple, switch defining $return by given type (doing whatever switch can possibly do with $data). Eg I can send year 1865 as $data and if $type is "fromYear" and $data is_numeric, it'll do whatever it's supposed to do.
leFunction ((string) $type,(array) $data) , this is where it gets tricky. Idea was that with this second option I can pass same args as ("fromYear", array("year" => 1865, ....) ) then check if is_numeric($data["year"]) and continue with same code.
But when I combined both pieces together I got this not so great if:
if (is_numeric($data) || (is_array($data) && isset($data["year"])))
Then I replaced second part with function from parent obj :
if (is_numeric($data) || is_numeric($this->setIfGet("year", $data)))
func:
/**
* #param $needle string key
* #param $haystack array source
* #param bool $null make true if value of $needle could be null
* #return bool
*/
protected function setIfGet($needle, $haystack, $null = false)
{
return (isset($haystack[$needle])) ? $haystack[$needle] : ($null) ? (array_key_exists($needle, $haystack) ? $haystack[$needle] : false): false;
}
But here's the problem: If I want to echo year from $data argument I need to do
if (...) {
echo $data;
...
}
but it wont work if $data was array and year which I want to echo is in
$data["year"];
How can I get it work for both cases for 1 echo.
I think I found the answer to my own question:
if (is_numeric($newData = $data) || is_numeric($newData = self::setIfGet("year", $data))){
echo $newData;
Good morning,
I need to truncate a string with a specific delimiter character.
For example with that string:
myString = 'customname_489494984';
I would like to strip automatically every string parts after "_"
(in this case "489494984").
Is there a function in order to truncate the string part after a specific
delimiter?
Many thanks!
François
You can also use strstr() which finds the first occurrence of a string:
$myString= "customname_489494984";
echo strstr($myString, '_', true);
Here's my reference: http://php.net/manual/en/function.strstr.php
Use a simple combo of substr and strpos:
$myString = 'customname_489494984';
echo substr($myString, 0, strpos($myString, '_'));
BONUS - Wrap it in a custom function:
function truncateStringAfter($string, $delim)
{
return substr($string, 0, strpos($string, $delim));
}
echo truncateStringAfter('customname_489494984', '_');
Try this,It will remove anything after "_".
$string= 'customname_489494984';
$string=substr($string, 0, strrpos($string, '_'));
The problem with other straightforward approaches is that if the String doesn't contain “_” then an empty String will be returned. Here is a small StringUtils class (part of a larger one) that does that with beforeFirst static method in a multibyte safe way.
var_dump(StringUtils::beforeFirst("customname_489494984", "_"));
class StringUtils
{
/**
* Returns the part of a string <b>before the first</b> occurrence of the string to search for.
* #param <b>$string</b> The string to be searched
* #param <b>$search</b> The string to search for
* #param <b>$caseSensitive boolean :optional</b> Defines if the search will be case sensitive. By default true.
* #return string
*/
public static function beforeFirst($string,$search,$caseSensitive = true)
{
$firstIndex = self::firstIndexOf($string, $search,$caseSensitive);
return $firstIndex == 0 ? $string : self::substring($string, 0 , $firstIndex);
}
/**
* Returns a part of the string from a character and for as many characters as provided
* #param <b>$string</b> The string to retrieve the part from
* #param <b>$start</b> The index of the first character (0 for the first one)
* #param <b>$length</b> The length of the part the will be extracted from the string
* #return string
*/
public static function substring($string,$start,$length = null)
{
return ( $length == null ) ? ( mb_substr($string, $start) ) : ( $length == 0 ? "" : mb_substr($string, $start , $length) );
}
/**
* Return the index of <b>the first occurance</b> of a part of a string to the string
* #param <b>$string</b> The string to be searched
* #param <b>$search</b> The string to search for
* #param <b>$caseSensitive boolean :optional</b> Defines if the search will be case sensitive. By default true.
* #return number
*/
public static function firstIndexOf($string,$search,$caseSensitive = true)
{
return $caseSensitive ? mb_strpos($string, $search) : mb_stripos($string, $search);
}
/**
* Returns how many characters the string is
* #param <b>$string</b> The string
* #return number
*/
public static function length($string)
{
return mb_strlen($string);
}
}