Phone number format received from twilio - php

I am storing sms received from twilio in a database so I can use them later. When I did this in the sandbox it worked. However when I upgraded to a regular phone number the number received is the same as was sent to, but +1 (or for xxxxxxxxxx where the x's are the original number, it looks more like 1xxxxxxxxxx+)
I therefore changed the mysql_query to the following: but it is still not working. What can be done to recognize that this is the original phone number?
<?php
$starttime = time();
$number = $_POST['number'];
$number1 = "1" . $number;
$number2 = $number . "1";
$number3 = "+1" . $number;
$number4 = $number . "+1";
$number5 = "+" . $number . "1";
$number6 = "1" . $number . "+";
$number7 = $number."1+";
$received = mysql_query("SELECT * FROM sms_received
WHERE (responder='$number' OR responder='$number1'
OR responder='$number2' OR responder='$number3'
OR responder='$number4' OR responder='$number5'
OR responder='$number6' OR responder='$number6')
AND (body='y' OR body='yes' OR body='Y' OR body='Yes' OR 'yea' OR 'Yea')
AND timestamp BETWEEN ".date('Y-m-d H:i:s', strtotime($starttime))." AND NOW()");
?>
But still, nothing is being received. Any ideas how else I can check whether an sms has been received from the user? I can see in the database that it's there... but the mysql isn't finding it. It worked before, when the number sent was identical to the number received from, but with the added +1 it screws it up. (the code before just had WHERE responder = '$number' and it worked, but the additional variables didn't help it).
Does this code have too many OR's? Is that even a problem?
UPDATE:
Thanks, here is the function I'm using to strip the number down to xxxxxxxxxx format, before saving it to the database:
function checkPhone($responder){
$items = Array('/\ /', '/\+/', '/\-/', '/\./', '/\,/', '/\(/', '/\)/', '/[a-zA-Z]/');
$clean = preg_replace($items, '', $responder);
if (substr($clean, 0, 1) == "1") {
return substr($clean, 1, 10);
}
else {
return substr($clean, 0, 10);
}
}
$number = checkPhone($responder);

Twilio returns numbers in a format called E.164, which is an internationally recognized standard for phone number formatting.
In general, it's best practice to standardize the number to E164 BEFORE you store it in the database. That way you don't have to worry about storing different data with two different copies of the same number - eg 925-555-1234 and (925) 5551234.
Google has a libphonenumber library that will convert numbers for you. It works with Javascript, C++, Java, and Python.
If you are using PHP, and only using US/Canadian numbers, you can write a function to normalize phone numbers, that does something like the following:
- Strip out all non number characters from the phone number
(parentheses, dashes, spaces) - you can use a function like preg_replace
- if the phone number begins with a +1, do nothing
- if the phone number begins with a 1, add a +
- else, add a +1 to the beginning of the number.
- finally, store it in the database.
I hope that helps - please let me know if you have more questions.
Kevin

Your last or is redundantly $number6, it should be $number7.
Aside from that, you can do a few different things, such as in:
responder in ('$number', '$number1', '$number2', '$number3', '$number4', '$number5', '$number6', '$number7')
Or something like this:
responder like '%$number%'

Use a regular expression.
preg_match_all("{[0-9]+}",$number,$m);
$norm_num="+".implode($m[0]);
if(strlen($norm_num)<6)
exit('Too short!');
mysql_query("SELECT * FROM sms_received
WHERE responder='%$norm_num%'
AND body IN ('y','yes','Y','Yes','yea','Yea')
AND timestamp BETWEEN ".date('Y-m-d H:i:s', strtotime($starttime))." AND NOW()");

Related

how to generate unique random numbers in php?

I am generating random numbers using php random function, but I want the generated number should be unique and it should not be repeated again.
----------
php code
$number = rand(100,100000); //a six digit random number between 100 to 100000
echo $number;
----------
but I am using this function for multiple times in my code for users so at very rare case there should be a chance of generating same number again. how can i avoid that.
I would do this:
You said you have branches. The receipt id could look something like this:
$dateString = date('Ymd'); //Generate a datestring.
$branchNumber = 101; //Get the branch number somehow.
$receiptNumber = 1; //You will query the last receipt in your database
//and get the last $receiptNumber for that branch and add 1 to it.;
if($receiptNumber < 9999) {
$receiptNumber = $receiptNumber + 1;
}else{
$receiptNumber = 1;
}
Update the receipt database with the receipt number.
$dateString . '-' . $branchNumber . '-' . $receiptNumber;
This will read:
20180406-101-1
This will be unique(Provided you do less than 10,000 transactions a day.) and will show your employees easily readable information.
If you are storing users in DB you should create column [ID] as primary key with auto increment and that would be best solution.
In other case I'd recommend you to simply store all user id's in ascending order from N to M by reading last ID and adding 1 to it because I see no real gain from random order that only adds complexity to your code.
There are many ways, example:
$freq = [];
$number = rand(100,100000);
$times = 10;
while($times-- > 0)
{
while(in_array($number, $freq))$number = rand(100,100000);
$freq[] = $number;
echo $number . "<br>";
}
This will print 10 random unique numbers.
random_int
(PHP 7)
<?php
$number = random_int(100, 100000);
echo $number;
All you need to do is use timestamp in php as timestamp never cross each other hence it will always generate unique number.You can use time() function in php.
The time() function is used to format the timestamp into a human desired format. The timestamp is the number of seconds between the current time and 1st January, 1970 00:00:00 GMT. It is also known as the UNIX timestamp.
<?php
$t=time();
echo $t;
?>
Also you add a rand() function and insert it in front of the $t to make it more random as if few users work at same time then the timestamp might collide.
<?php
$number = rand(100,100000);
$t=time();
$random = $number.''.$t;
echo $random;
?>
The above will reduce the chance to timestamp collide hence making the probability of number uniqueness almost 100%.
And if you make your column unique in your database then the php wont insert the number hence this bottleneck will ensure you will always get a unique random number.
bill_id not null unique
If you are using it for something like user id, then you can use uniqid for that. This command gets a prefixed unique identifier based on the current time in microseconds.
Here's how to use it:
string uniqid ([ string $prefix = "" [, bool $more_entropy = FALSE]] )
Where prefix is used if you are generating ids for a lot if hosts at the same time, you can use this to differentiate between various hosts if id is generated at the same microsecond.
more_entropy increases the likeness of getting unique values.
Usage:
<?php
/* A uniqid, like: 4b3403665fea6 */
printf("uniqid(): %s\r\n", uniqid());
/* We can also prefix the uniqid, this the same as 
 * doing:
 *
 * $uniqid = $prefix . uniqid();
 * $uniqid = uniqid($prefix);
 */
printf("uniqid('php_'): %s\r\n", uniqid('php_'));
/* We can also activate the more_entropy parameter, which is 
 * required on some systems, like Cygwin. This makes uniqid()
 * produce a value like: 4b340550242239.64159797
 */
printf("uniqid('', true): %s\r\n", uniqid('', true));
?>
this code must work
some description about code:
generate unique id
extract numbers form unique id with regex
gathering numbers from regex with a loop
<?php
$unique = uniqid("",true);
preg_match_all("!\d+!", $unique ,$matches);
print_r($matches);
$numbers = "";
foreach($matches[0] as $key => $num){
$numbers .= $num;
}
echo $numbers;

setting accountexpires date with PHP and LDAP

I'm having trouble setting the 'accountexpires' and wondered if anyone knows a way around it, I believe it's because I have a 18 digit number. I have a form where someone sets a date, I need to set the account to expire then, if I provide the number as a hardcoded string it works, but I cannot convert the finished calculation to a string. Anyone know any way around this? thanks.
<?php
$currentTimeUnix = 1442383989; //this will vary depending on user's input
$secondsBetween1601and1970 = 11644473600;
$timesAdded = $currentTimeUnix + $secondsBetween1601and1970;// comes to 13086857589
$nanoseconds = $timesAdded * 10000000; //comes to 130868575890000000
echo $nanoseconds; //displays 1.3086857589E+017
echo (string)$nanoseconds; //displays 1.3086857589E+017
echo strval($nanoseconds); //displays 1.3086857589E+017
?>
PHP is kind of bad with large numbers but sprintf can help. try:
echo sprintf( '%018.0f', $nanoseconds );
-> 130868575890000000
Alternatively you change the "precision" setting where precision is described:
precision integer
The number of significant digits displayed in floating point numbers.
ini_set("precision",20);
echo $nanoseconds;
-> 130868575890000000
Thanks for this. Been testing true out the net but nothing worked until i stumbled on this solution:
$expiredate = strtotime($values["expires"]);
$currentTimeUnix = $expiredate;
$secondsBetween1601and1970 = 11644473600;
$timesAdded = $currentTimeUnix + $secondsBetween1601and1970;
$nanoseconds = $timesAdded * 10000000;
$expires = sprintf('%018.0f',$nanoseconds);

PHP: Using a regex to remove decimals out of IP address

I currently have a liking function on my images site that stores user IPs in the database against unique $imgids.
The IPs are currently stored as strings. To save space, I'd like to store the IPs not as strings with decimal points, but as 32-bit integers (1 bit per integer vs 1 byte per char in the string). I think this could save considerable space because I have the potential for n unique IPs to like x images...
So given string "109.181.156.221" that'd be a max of 12 bytes for the numbers, + 3 bytes per decimal point... so 15 bytes * 5000 IPs * 10 image IDs = 7.1 Mb
Versus 32bit 109181156221, 4 bytes * 5000 IPs * 100 image IDs = 2 Mb
So, before I inser the IP, I'd like to use a regex to remove decimals, and then store the IP as a number... "109.181.156.221" -> 109181156221
I'm new to Regexs, but I've tried this, but it won't work:
$ipINT = preg_replaceAll("\\.+$", "" , $ipString);
So my questions are:
1) Would the space savings even matter in a Mysql database? Is this
worth the trouble?
2) Where am I off with my regex?
3) Would I be able to convert it back if I'm trying to read it?
Any thoughts?
Thanks!
There are different ways to do this:
The right way:
By letting the database do the conversion for you. You have to store the ip in the database as INT(10) UNSIGNED and use INET_ATON & INET_NTOA:
SELECT INET_ATON("109.181.156.221"); // result 1840618717
SELECT INET_NTOA("1840618717"); // result 109.181.156.221
The alternative way:
By using PHP internal functions ip2long() & long2ip() and then store it in the DB:
$ipINT = ip2long('109.181.156.221'); // result 1840618717
$ip = long2ip('1840618717'); // result 109.181.156.221
The non-standard way:
By removing the dots and adding "0" if needed to be able to convert it back:
function ip2int($ip){
$chunks = explode(".", $ip);
$int = '';
foreach($chunks as $chunk){
$int .= str_pad($chunk, 3, '0', STR_PAD_LEFT);
}
return $int;
}
function int2ip($int){
$chunks = str_split($int, 3);
$c = count($chunks);
$ip = ltrim($chunks[0], '0');
for($i=1;$i<$c;$i++){
$ip .= '.' . ltrim($chunks[$i], '0');
}
return($ip);
}
echo ip2int("109.1.156.5") . '<br>'; // result 109001156005
echo int2ip("109001156005"); // result 109.1.156.5
Fixing your RegEx:
$ip = "109.181.156.221";
$replace = preg_replace("/\./", "", $ip); // This will remove all the dots
echo $replace; // result 109181156221
You can use ip2long(), then it should fit in an unsigned int column.
Use the ip2long() function to store IP addresses - Unsigned INT(10) should be great.
Use long2ip() to decode.
http://php.net/manual/en/function.ip2long.php
Your solution wouldn't work for IP Address like 1.123.123.123, as you wouldn't know where to restore the decimal point. The correct way to store an IP address would be with the method described above.
if you want to extract only digits you dont need regex you can just use:
filter_var('109.181.156.221', FILTER_SANITIZE_NUMBER_INT);
will give you 109181156221
but i dont think you would be able to convert it back to IP form.
I would store it with dots.

How do I amend an existing javascript to display currency values including cents?

A site I'm working on (which I inherited...I don't know javascript that well) has code currently set up to display ".00" at the end of any number in the database (a PHP include page, actually) such that it displays as currency on an online form.
My client now wants to add an amount to the list which includes cents ($5.50), and I need help modifying or amending the script so I can include these non-whole currency amounts.
Here is the snippet of the script that (I think/presume) addresses the currency formatting:
function CurrencyFormatted(amount)
{
var i = parseFloat(amount);
if(isNaN(i)) { i = 0.00; }
var minus = '';
if(i < 0) { minus = '-'; }
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if(s.indexOf('.') < 0) { s += '.00'; }
if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
s = minus + s;
return s;
}
Is there a way to add to or change this code so that I can display the specific cents needed for this one (and future similar) amounts?
That code is doing some interesting rounding things, which I can't really address, but to format a number with a fixed number of digits to the right of the decimal, use the toFixed function on numbers:
var n = 1.2345;
n.toFixed(2); // "1.23"
Note that it does rounding, so:
(1.234).toFixed(2); // "1.23"
(1.235).toFixed(2); // "1.24"
(You don't need the parens when you're calling toFixed on a variable, but you do need them when calling it on a literal as I did in the two examples above. Naturally, in your case, you'll be using a variable so no need for them.)
Re your comment/question below:
Thanks for the quick replies! I guess I should have said I don't know javascript AT ALL, so my questions are: 1) where do I insert the codes you offer above into my existing code...
1) The code you quoted in your question is doing a bunch of operations on the number fed into it, including adding half a cent to it before trying to round it to two digits (in a very non-optimal way). If the goal now is to faithfully reproduce a rounded-to-two-digits version of the number fed in (none of this adding half-a-cent stuff), you can replace the entire function with this:
function CurrencyFormatted(amount)
{
return parseFloat(amount).toFixed(2);
}
If you want to continue adding half a cent to it:
function CurrencyFormatted(amount)
{
return (parseFloat(amount) + 0.005).toFixed(2);
}
...and 2) will this allow all of my existing other numbers to continue displaying as they are (e.g. "25" in my include file displays as "25.00")?
Any number (or numeric string) you feed into the above will be formatted with two digits to the right of the decimal, even if those digits are 00. So with the above, CurrencyFormatted("25") will return "25.00".
...Or do I use this code you suggest to replace part or all of the sample code I posted, and thus, would I then need to change all my database numbers to accommodate this? (i.e. should I add two zeros to the end of all my whole numbers now? (25 becomes 2500, etc.)
You don't need to add .00 to whole numbers in the database or anything like that.
If you wanted todo this with PHP checkout money_format() heres an example:
<?php
$value = 5;
setlocale(LC_MONETARY, 'en_US');
echo '$'.money_format('%i', $value) . "\n";//$5.00
$value = 5.545;
setlocale(LC_MONETARY, 'en_US');
echo '$'.money_format('%i', $value) . "\n";//$5.54
$value = 9.99;
setlocale(LC_MONETARY, 'en_US');
echo '$'.money_format('%i', $value) . "\n";//$9.99
?>

Php set value as a number

How do I output a value as a number in php? I suspect I have a php value but it is outputting as text and not as a number.
Thanks
Here is the code - Updated for David from question below
<?php
if (preg_match('/\-(\d+)\.asp$/', $pagename1, $a))
{
$pageNumber = $a[1];}
else
{ // failed to match number from URL}
}
?>
If I call it in: This code it does not seem to work.
$maxRows_rs_datareviews = 10;
$pageNum_rs_datareviews = $pagename1; <<<<<------ This is where I want to use it.
if (isset($_GET['pageNum_rs_datareviews'])) {
$pageNum_rs_datareviews = $_GET['pageNum_rs_datareviews'];
}
If I make page name a static number like 3 the code works, if I use $pagename1 it does not, this gives me the idea $pagename1 is not seen as a number?
My stupidity!!!! - I used $pagename1 instead of pageNumber
What kind of number? An integer, decimal, float, something else?
Probably the easiest method is to use printf(), eg
printf('The number %d is an integer', $number);
printf('The number %0.2f has two decimal places', $number);
This might be blindingly obvious but it looks like you want to use
$pageNum_rs_datareviews = $pageNumber;
and not
$pageNum_rs_datareviews = $pagename1;
echo (int)$number; // integer 123
echo (float)$number; // float 123.45
would be the easiest
I prefer to use number_format:
echo number_format(56.30124355436,2).'%'; // 56.30%
echo number_format(56.30124355436,0).'%'; // 56%
$num = 5;
echo $num;
Any output is text, since it's output. It doesn't matter what the type of what you're outputting is, since the human eye will see it as text. It's how you actually treat is in the code is what matters.
Converting (casting) a string to a number is different. You can do stuff like:
$num = (int) $string;
$num = intval($string);
Googling php string to number should give you a beautiful array of choices.
Edit: To scrape a number from something, you can use preg_match('/\d+/', $string, $number). $number will now contain all numbers in $string.

Categories