Asked  7 Months ago    Answers:  5   Viewed   29 times

What's the best way to determine whether or not a string is the result of the serialize() function?

https://www.php.net/manual/en/function.serialize

 Answers

23

I'd say, try to unserialize it ;-)

Quoting the manual :

In case the passed string is not unserializeable, FALSE is returned and E_NOTICE is issued.

So, you have to check if the return value is false or not (with === or !==, to be sure not to have any problem with 0 or null or anything that equals to false, I'd say).

Just beware the notice : you might want/need to use the @ operator.

For instance :

$str = 'hjkl';
$data = @unserialize($str);
if ($data !== false) {
    echo "ok";
} else {
    echo "not ok";
}

Will get you :

not ok


EDIT : Oh, and like @Peter said (thanks to him!), you might run into trouble if you are trying to unserialize the representation of a boolean false :-(

So, checking that your serialized string is not equal to "b:0;" might be helpful too ; something like this should do the trick, I suppose :

$data = @unserialize($str);
if ($str === 'b:0;' || $data !== false) {
    echo "ok";
} else {
    echo "not ok";
}

testing that special case before trying to unserialize would be an optimization -- but probably not that usefull, if you don't often have a false serialized value.

Wednesday, March 31, 2021
 
Nate
answered 7 Months ago
40

A number like 6.2 can't be represented exactly using floating-point math in computers as there is no finite base-2 representation of it. What you are seeing when echo-ing the number is something intended for human reading, and thus the value will be rounded to what floats can provide in accuracy (about 6 decimal places for 32-bit and 17 for 64-bit FP values).

When serializing those values, however, you really want the exact value (i. e. all bits that are in there) and not just the nearest "nice" value. There could be more than one float/double representation which evaluates to approximately 6.2 and when serializing you usually really want to store he exact values to the last bit you are having in order to restore them correctly. That's why you're getting ridiculous "accuracy" in values there. It's all just to preserve the exact bit representation of what you started with.

But why exactly do you want to control the serialized output that tightly? I mean, it's just there so you can round-trip your data structure and read it back in later. You certainly don't want to use that serialized representation somewhere in output for humans or so. So if it's just about "nice-looking" values, you shouldn't use serialize which has an entirely different purpose.

Wednesday, March 31, 2021
 
dmp
answered 7 Months ago
dmp
72

After some debugging I found the solution myself.

The problem is, when User Entity was implementing the UserInterface, the user provider(actually the Doctrine, behind the scene) tried to Serializing the User object to store it in the session but because of the file that I assigned it to this class, it fails it's career!

To solve the problem, first I tried to fetch separate User object from database but unfortunately Doctrine gave me the exact reference of the User object again.(That's not a bug. Thanks to Doctrine. It's too smart to query as less as possible).

Second, I clone the User object myself in the controller before sending it to the UserType form, and then everything went well.

But that is not the best practice because you may have some other problems with registration, profile update or other scenarios that you may have with User class.

In my application, I added another entity called Media and it stores the files with the file system and each entity like User which need some media (Like user avatar here), just have a ManyToOne relationship with this entity. In this case you can just save the name file as string in avatar field in User class.

You may have some other designs in your application but as I experienced, Do not assign a File field directly to the User entity which is implementing UserInterface!

Wednesday, March 31, 2021
 
Uours
answered 7 Months ago
11
using System.Text.RegularExpressions;

…

var sourceString = "put your string here";
var match = Regex.Match(sourceString, @"b(d{1,3}.d{1,3}.d{1,3}.d{1,3})b");
if(match.Success) Console.WriteLine(match.Captures[0]);

This will match any IP address, but also 999.999.999.999. If you need more exactness, see details here: http://www.regular-expressions.info/examples.html

The site has lots of great info an regular expressions, which is a domain-specific language used within most popular programming languages for text pattern matching. Actually, I think the site was put together by the author of Mastering Regular Expressions.

update

I modified the code above to capture the IP address, as you requested (by adding parentheses around the IP address pattern). Now we check to make sure there was a match using the Success property, and then you can get the IP address using Captures[0] (because we only have one capture group, we know to use the first index, 0).

Wednesday, August 25, 2021
 
Gabriele Mariotti
answered 2 Months ago
66

use a regex. This one only matches if it starts with, contains, and ends with only letters and spaces.

^[ A-Za-z]+$

In Java, initialize this as a pattern and check if it matches your strings.

Pattern p = Pattern.compile("^[ A-Za-z]+$");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
Thursday, October 14, 2021
 
bux
answered 2 Weeks ago
bux
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :