PostgreSQL error when bitvalue is false - php

I am having a little trouble saving bit-values into my PostgreSQL-DB using PDO. Whenever the bit(bool) is false i get this error
Warning: PDOStatement::execute(): SQLSTATE[22026]: String data, length mismatch: 7
ERROR: bit string length 0 does not match type bit(1) in /var/www/html/application/models/Database.php on line 75
The code is a little complicated to show, but here is what goes into the DB-class.
UPDATE users SET name=:name,email=:email,address=:address,zip=:zip,joindate=:joindate,phone=:phone,password=:password,activationcode=:activationcode,birthdate=:birthdate,lastdigits=:lastdigits,driverlicense=:driverlicense,e_presentation=:e_presentation,e_showphone=:e_showphone,e_showaddress=:e_showaddress,e_radius=:e_radius,e_showinsearch=:e_showinsearch,w_presentation=:w_presentation,w_showphone=:w_showphone,w_showaddress=:w_showaddress,w_radius=:w_radius,w_showinsearch=:w_showinsearch WHERE id=:id
And the data that is bound to the parameters
Array ( [:name] => My Name [:email] => myemail#gmail.com [:address] => My Address [:zip] => 79133 [:joindate] => 2012-09-18 12:39:56.769584 [:phone] => 073 917 13 97 [:password] => c6d18ac44b378ff3cecf09d9ebec31ad301c4394d7e1sdfjksc81cd3fbf47777f8df0ac9f33d14da18d71b76fc9c3e1210cb2efcabf6ed66f779d [:activationcode] => [:birthdate] => 1993-08-05 [:lastdigits] => 5079 [:driverlicense] => 0 [:e_presentation] => Test [:e_showphone] => 1 [:e_showaddress] => 1 [:e_radius] => 10 [:e_showinsearch] => 1 [:w_presentation] => Test [:w_showphone] => 1 [:w_showaddress] => 1 [:w_radius] => 10 [:w_showinsearch] => 1 [:id] => 28 ) 1
A quick Google-search shows me that others had the same problem, but no solution to it.

Maybe you are better served with a boolean type instead of bit(1)?
If you actually need to convert a boolean value to bit(1), a direct cast doesn't work:
select FALSE::bit(1), TRUE::bit(1)
But this works:
select FALSE::int::bit(1), TRUE::int::bit(1)
Cast to integer first, an then to bit.

If we consider that a bit is a number that is either 1 or 0, then false in php is not a number.
<? echo false; ?> prints an empty string, not the number 0.
In a lot of other situations in php, 0 and false will be equivalent, but they're still not the same thing, and from the point of view of PostgreSQL, an empty string as the value of a bit is not acceptable.
The php code should convert false to 0 when passing the bit value to execute() or similar.
Using
$sth->bindParam(':param', $value, PDO::PARAM_INT);
would also work when $value is false, since that would force a conversion to 0.

Related

Strange "undefined index" error solved with type declaration

Figured out a strange (to me) undefined index error and wanted to share in case anyone else was banging their heads against the wall.
Short answer: Type casting the argument INTO a function made sure the array that got returned could be used in strings with no "undefined index" error.
Here's what happened: The code took a value from the URL ($params),
passed it into a function to get a big array of data back,
then put one of the elements of the array into a string.
$wid = $params[2] ?? null; // get id from URL parameter
$wk = \Workshops\get_workshop_info($wid); // get a big array
if (isset($wk['title'])) {
$message = "The title of this workshop is: {$wk['title']}"; // no warning
}
$message = "The title of this workshop is: {$wk['title']}"; // undefined index?
print_r($wk);
I got an "undefined index" when I tried to include $wk['title'] in a string outside of an "isset" clause.
The output for print_r($wk) showed the 'title' index existing with a value. (I edited out some of this array that had people's emails)
Array
(
[id] => 425
[title] => Sketch Writing
[start] => 2021-11-07 17:00:00
[end] => 2021-11-07 19:30:00
[cost] => 225
[capacity] => 8
[notes] => A new WGIS sketch writing class for advanced sketch students and brand new students alike. If you’re an experienced writer, come hone your craft. Learn new sketch technique, new styles, new formats. If you’re brand new, come learn how to take your fun idea and turn it into a stageable, shootable, performable sketch. Great for improv students who want to transition into writing. Whatever your background- the focus will be on writing in your voice. Take the stuff that YOU find funny and turn it into a great script. This is an active writing class. You’ll leave with at least two complete sketches by the end of the five weeks!
[location_id] => 8
[sold_out_late] => -1
[when_public] => 1969-12-31 16:00:00
[teacher_id] => 8
[co_teacher_id] =>
[reminder_sent] => 0
[application] => 0
[address] =>
[city] =>
[state] =>
[zip] =>
[place] => Online
[lwhere] =>
[soldout] => 0
[showstart] => Sun Nov 7 5pm (PDT)
[showend] => 7:30pm (PDT)
[when] => Sun Nov 7 5pm-7:30pm (PDT)
[short_title] => Sketch Writing
[costdisplay] => $225 USD
[total_class_sessions] => 5
[total_show_sessions] => 0
[total_sessions] => 5
[time_summary] => 5 classes
[full_when] => Sun Nov 7 5pm-7:30pm (PDT)<br>
Sun Nov 14 5pm-7:30pm<br>
Sun Nov 21 5pm-7:30pm<br>
Sun Nov 28 5pm-7:30pm<br>
Sun Dec 5 5pm-7:30pm<br>
[upcoming] => 1
[actual_revenue] => 0
[enrolled] => 5
[waiting] => 0
[dropped] => 0
[applied] => 0
[paid] => 0
[open] => 3
)
The solution surprised me -- I had to explicitly cast the parameter I used in my function to be an int. This fixed everything:
$wid = (int) ($params[2] ?? 0);
$wk = \Workshops\get_workshop_info($wid); // get a big array
PHP thought the argument $wid was a string. But the function get_workshop_info() assumed it was getting an int. There was no error thrown because I had not done any type declaration in get_workshop_info(). But passing in what PHP thought was a string got back an array that I just couldn't use without getting undefined index errors.
I put type declarations in all my function arguments after this.
This code is from a handmade huge MVC nightmare that I've created. I didn't even bother asking because there were just so many places that could be causing problems.
I had to explicitly cast the parameter I used in my function to be an int. This fixed everything:
$wid = (int) ($params[2] ?? 0);
$wk = \Workshops\get_workshop_info($wid); // get a big array
PHP thought the argument $wid was a string. But the function get_workshop_info() assumed it was getting an int. There was no error thrown because I had not done any type declaration in get_workshop_info(). But passing in what PHP thought was a string got back an array that I just couldn't use without getting undefined index errors.

preg_match_all returning arrays

I recently made a small script to catch any URL's that pass through a textarea based on a form submit.
The regular expression im using is:
'/([\w]+).(local|test|stage|live).site.example.com/'
and if submit:
<p>body</p> <p>uk2.local.site.example.net
training.test.site.example.net</p>
<p>www.google.com</p>
<p>sd2.test.site.example.net</p>
i am returned with an array that contains:
0 => array(3
0 => uk2.local.site.example.net
1 => training.test.site.example.net
2 => sd2.test.site.example.net
)
1 => array(3
0 => local
1 => test
2 => test
)
I'm not sure why i get the second array and wanted to look to clean it up.
Use non-capture group, also escape the dots:
'/(\w+)\.(?:local|test|stage|live)\.site\.example\.com/'
// here __^^

Searching through multiple fields in SphinxSearch (PHP)

I have the following code:
$this->api = new App_Other_SphinxSearch();
$this->api->SetServer($host, $port);
$this->api->SetConnectTimeout(1);
$this->api->SetArrayResult(true);
$results = $this->api->Query("#(title,content) test", 'members');
echo "<pre>";print_r($results);die;
According to their documentation, a syntax like #(field_1,field_2) query should return docs which match the string query in either field_1 or field_2.
The PHP SDK returns something entirely different:
Array
(
[error] =>
[warning] =>
[status] => 0
[fields] => Array
(
[0] => title
[1] => content
)
[attrs] => Array
(
[created] => 2
[content] => 7
)
[total] => 0
[total_found] => 0
[time] => 0.000
[words] => Array
(
[title] => Array
(
[docs] => 10
[hits] => 34
)
[content] => Array
(
[docs] => 34
[hits] => 139
)
[test] => Array
(
[docs] => 26
[hits] => 34
)
)
)
There is no matches key in the array, however it got some hits. I don't really understand why this is happening, especially because if I try the same query from the command line, everything works correctly.
Any help?
Edit: Querying like this works though: #* test. Not really what I want though, cause that searches in all fields.
[total_found] => 0 says there where no matches.
The words array, just tells you now many documents and how many times that word appears in ANY (and all) fields. (WITHOUT regard to your specific query)
Sphinx caches those word stats, which help it make quick sanity checks on queries. When the query runs it can end up not matching any documents (because only then does it apply the field level filters), even though the individual words are found.
That explains your misinpretation of the results, but not why getting the results you get.
You are entering a Extended Mode query (as evidenced by the link to the sphinx documentation) , but the sphinx API defaults to ALL query mode. Notice also that title and content are in the words array, so are being taken as plain keywords not as syntax.
So you need to include a
$this->api->SetMatchMode(SPH_MATCH_EXTENDED);
btw, #* test, works because the #* are simply ignored in ALL query mode.

How to handle key in PHP array if the key contains japanese characters

I have this array:
[ID] => 荒川之下流三十景-その二十三「赤羽之景」__35.79_139.72
[Email] =>
[InBuildingAddress] =>
[Price] =>
[Street] =>
[Title] => 荒川之下流三十景 その二十三「赤羽之景」
[Website] =>
[Zip] =>
[Rating Star] => 0
[Rating Weight] => 0
[Latitude] => 35.7865334803033
[Longitude] => 139.716800710514
[Building] =>
[City] => Unknown_Japan
[OpeningHour] =>
[TimeStamp] => 0000-00-00 00:00:00
[CountViews] => 0
Then I do something like this:
$output[$info['ID']] = $info; //mess up here
$tes = $info['ID']['Title'];
Well guess what: it messes up. The reason why it may mess up is because $info['ID'] is not ascii. Yet I am using it as a key for $output[$info['ID']].
Basically even though the content of an array in PHP can be Japanese. Is this true?
What's wrong? The error I got is:
Debug Warning: /sdfdsfdf/api/test2.php line 36 - Cannot find element ????????-???????????__35.79_139.72 in variable
Debug Warning: /sdfdsfdf/api/test2.php line 36 - main() [function.main]: It is not safe to rely on the system's timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Krasnoyarsk' for '7.0/no DST' instead
So many question marks.
Why is this happening? What's really going on inside PHP? Where can I learn more of such things? Most importantly, what would be the best way to handle this situation? Should I tell PHP to internally always use UTF-8? Can PHP arrays inherently not have non-ASCII values?
Running this:
$utf8str = '荒川之下流三十景-その二十三「赤羽之景」__35.79_139.72';
$arr = Array(
$utf8str => $utf8str,
);
var_dump($arr);
$arr[$utf8str] = "test";
var_dump($arr);
I get this:
array
'荒川之下流三十景-その二十三「赤羽之景」__35.79_139.72' => string '荒川之下流三十景-その二十三「赤羽之景」__35.79_139.72' (length=72)
array
'荒川之下流三十景-その二十三「赤羽之景」__35.79_139.72' => string 'test' (length=4)
So PHP can handle utf8 charachers as the array key...
Regarding the date related warning, please use google first, its faster that asking questions and waiting for people to come up with answers to the same questions over and over (is suppose thats the reason you got downvoted)
google search

Get timestamp from base64Binary in PHP

A webservice returns a timestamp field in base64Binary format. It looks like this in SOAP response:
<a:TimeStamp>AAAAAAMpI9Q=</a:TimeStamp>
PHP __soapCall, however, b64_decode()s that and I get a binary string looking like ')#▒'. How do I get actual timestamp out of this? I tried to unpack('L') it but it gives me Array([1] => 0) as a result. Is there really zero i.e. 1970-01-01 or have I missed something?
This test program:
$b = "AAAAAAMpI9Q=";
$ts = base64_decode($b);
print_r(array_map("ord", str_split($ts)));
outputs:
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
[4] => 3
[5] => 41
[6] => 35
[7] => 212
)
showing that the base64-encoded string gives you an 8-character string when unpacked. So presumably it represents a 64-bit integer, which might be signed or unsigned, and no, it isn't zero.
Given the values above it looks like the value is 53027796 - is that what you're expecting?

Categories