What is the point of replace function in Memcache? - php

What is the point of replace function in PHP memcache if you can just use set? Even if there is a variable, set automatically replaces it, right?
Can you give me an example where it's better to use replace instead of set?
Thanks.

According to PHP.net:
Memcached::replace() is similar to Memcached::set(), but the operation fails if the key does not exist on the server.

Following on from ZoFreX's answer if you look at the comments here:
http://www.php.net/manual/en/memcache.set.php
You will see the following:
Using set more than once for the same key seems to have unexpected results - it does not behave as a "replace," but instead seems to "set" more than one value for the same key. "get" may return any of the values.
This was tested on a multiple-server setup - behaviour may be different if you only have one server.
So really and truly replace() will look for an existing key first, and then replace it (if it exists), whereas set() will just add the key. I imagine it's always best to use replace() first considering it returns FALSE if the key is not found, in which case you'd use add() rather than set() since you know for sure the key doesn't exist. This ensures that you won't have any unintended mishaps. So you're code could be something like:
$replace = Memcached::replace($key, $var);
if ( ! $replace)
{
$set = Memcached::add($key, $var);
}

Generally, replace should be used if the key is likely to be used frequently. Set/add/etc creates a brand new entry, and can lead to fragmentation and a lot of cleanup. Replace reuses the memory already allocated (if possible), and can be more stable and efficient. If it fails, using add/set will still work.

nope that's entirely wrong.
If you want to check and set a value you must use GETS + CAS.

Related

Multiple procedure assignment for self variable in one line

Is there any way a variable can be assigned from multiple procedures in one line?
For example:
$class_splits = explode("\\", $class_name);
$short_class_name = $class_splits[count($class_splits) - 1] ?? null;
Translated to this pseudo code:
$short_class_name = explode("\\", $class_name) => prev_result(count(prev_result) -1);
I don't have big expectations on this as I know it looks too "high-level" but not sure if newer versions of PHP can handle this.
Thanks.
You can use an assignment as an expression, then refer to the variable that was assigned later in the containing expression.
$short_class_name = ($class_splits = explode("\\", $class_name))[count($class_splits) - 1] ?? null;
That said, I don't recommend coding like this. If the goal was to avoid creating another variable, it doesn't succeed at that. It just makes the whole thing more complicated and confusing.
I believe you have an "X/Y Problem": your actual requirement seems to be "how to split a string and return just the last element", but you've got stuck thinking about a particular solution to that.
As such, we can look at the answers to "How to get the last element of an array without deleting it?" To make it a one-line statement, we need something that a) does not require an argument by reference, and b) does not require the array to be mentioned twice.
A good candidate looks like array_slice, which can return a single-element array with just the last element, from which we can then extract the string with [0]:
$short_class_name = array_slice(explode("\\", $class_name), -1)[0];
Since we no longer need to call count(), we can avoid the problem of needing the same intermediate value in two places.
Whether the result is actually more readable than using two lines of code is a matter of taste - remember that a program is as much for human use as for machine use.

How to pass a boolean argument to a function to act as a switch?

My apologies if the title isn't clear, but I find this difficult to describe. Basically, I have a function that looks for an instance of a class (the school kind) given a class ID number and a date. The function can also create a new class instance if desired.
function get_class_instance($class_id, $date, $create)
Inside the function is a database select on the class_instances table using the class_id and date as arguments. If a matching class_instance is found, its ID is returned. If none is found, there's a conditional for the create argument. If it's true, a new class_instance is created using a database insert and its ID is returned. If false, nothing is changed in the database and false is returned.
I'm still a beginner with PHP and coding generally, so I'm thinking there is probably a better way. The issue is that when calling the function, it might not be clear to someone why there is a boolean being passed.
$original_cinstance_id = get_class_instance($original_class_id, $original_date, 1);
Passing boolean flags to functions to make them do two different things instead of just one is considered a Code Smell in Robert Martin's Clean Code book. The suggested better option would be to have two functions get_whatever and create_whatever.
While a Code Smell depends on context, I think the boolean flag smell does apply in this case, because creating something is different from merely reading it. The former is a Command and the latter is a Query. So they should be separated. One changes state, the other doesn't. It makes for better semantics and separation of concerns to split them. Also, it will reduce the Cyclomatic Complexity of the function by one branch, so you will need one unit-test less to cover it.
Quoting https://martinfowler.com/bliki/FlagArgument.html
Boolean arguments loudly declare that the function does more than one thing. They are confusing and should be eliminated.
Quoting http://www.informit.com/articles/article.aspx?p=1392524
My reasoning here is that the separate methods communicate more clearly what my intention is when I make the call. Instead of having to remember the meaning of the flag variable when I see book(martin, false) I can easily read regularBook(martin).
Additional discussion and reading material:
https://softwareengineering.stackexchange.com/questions/147977/is-it-wrong-to-use-a-boolean-parameter-to-determine-behavior
https://medium.com/#amlcurran/clean-code-the-curse-of-a-boolean-parameter-c237a830b7a3
https://8thlight.com/blog/dariusz-pasciak/2015/05/28/alternatives-to-boolean-parameters.html
You can use a default value for create, so if you pass anything to it, it acts as a normal "get" operation for the database. Like this:
function get_class_instance($class_id, $date, $create = false);
You can query your ID's like this:
$class_id = get_class_instance(1, "18-10-2017");
You can then pass "true" to it whenever you need to create it on the database:
$class_id = get_class_instance(1, "18-10-2017", true);
Instead of passing a number value, you can pass a real boolean value like this:
$original_cinstance_id = get_class_instance($original_class_id, $original_date, true);
Also in the declaration of your function, you can specify a default value to avoid to pass the boolean each time:
function get_class_instance($class_id, $date, $create = false)
one option is to create an enumerator like so:
abstract class create_options {
const no_action = 0;
const create = 1;
}
so now your function call would look like this:
$original_cinstance_id = get_class_instance($original_class_id, $original_date, create_options::no_action);
in practice as long as your code is well commented then this isn't a major issue with boolean flags, but if you had a dozen possible options with different results then this could be useful.
As others have mentioned, in many languages you can also make an argument optional, and have a default behavior unless the caller specifically defines that argument.

Is it safe not to use array_key_exists() when checking if an item is in the array?

I know it's possible in PHP to check if the item is in the array this way:
if( my_array['item_one'] ){ # some code here... }
That's because if the item isn't, then null value (that equals to false or zero) is returned instead.
But will it always work? Will it always be safe to do it this way (because you know... PHP)?
This idiom is a bad idea. First, as noted in the comments, attempting to access a non-existent value in an array will generate an unknown index error. Second, and more important, 0 and FALSE are most definitely real values, but evaluating keys that point to such values with a snippet like you suggest will act as though they aren't there, which is just plain wrong.
To make a long story short - PHP has an excellent tool to check if an array contains a key - array_key_exists. There's no reason not to use it.

Guarding my methods against bad input

I have a method like this:
public function create (array $hash) {
$id = $hash[ID_KEY];
$this->store[$id] = $hash;
}
I want to guard it against bugs caused by bad input.
For instance, my code can mistakenly pass $hash with
$id = '' or $id = null,
in which case it will be stored silently referenced by null. Instead I want to see a warning and revise my code to get rid of it. So I guess the best way is to throw Exception:
if (! $id) throw new Exception("Hash with empty id");
Note that I am using empty strings as default values for several method arguments and for default return values, so this kind of bug can easily occur. (Using null instead of empty string here doesn't seem to change anything, even if it is not recommended by Uncle Bob.)
The problem is -- there are many methods like that. Is it really best practice to guard each of them for each argument that can become null but shouldn't?
For instance, another method does only reading. Then it seems there is no need to guard against null because nothing will ever be stored referenced by null, right? Or shall I still guard defensively, to prepare for the case I may somewhere in the future decide to allow storage referenced by null and forget to adjust the guards?
This sounds kind of the safest way but would clutter all methods with bulks of guarding code for all indices involved there. Is this really the best way?
EDIT.
I put more guards and indeed discovered few bugs that I wouldn't find otherwise. Also my tests didn't spot them.
Furthermore, it helped to better understand the role of read methods - to return value if found or return empty Array if not. The input $id = null goes under not found and hence also returns empty Array. That way the method is clean and consistent.
You can use PHP's is_null() and empty() to easily manage this kind of output.
Also I suggest you to write a list of function used only in debug (since you want to perfectionate your code). Call these function in each method you want to test and set a constant like DEBUG_MODE to handle the debug functions' behavior. All of this could be also done using unit testing, which would require more attention and time. But if you have both or want to learn something new, unit testing is clearly a better choice.
Also it is a good practice to handle ALL CASES you can think of. For instance, if your "reading method" expects not to find a null value (because you think there are none because you eradicated by testing over testing), if this "reading method" happens to find a null value a "ugly" PHP error would be shown somewhere, or worse, if error_report is shut you might never see a problem, or even worse, the code might continue its execution and utterly damage further data.

Should you verify parameter types in PHP functions?

I'm used to the habit of checking the type of my parameters when writing functions. Is there a reason for or against this? As an example, would it be good practice to keep the string verification in this code or remove it, and why?
function rmstr($string, $remove) {
if (is_string($string) && is_string($remove)) {
return str_replace($remove, '', $string);
}
return '';
}
rmstr('some text', 'text');
There are times when you may expect different parameter types and run different code for them, in which case the verification is essential, but my question is if we should explicitly check for a type and avoid an error.
Yes, it's fine. However, php is not strongly typed to begin with, so I think this is not very useful in practice.
Additionally, if one uses an object other than string, an exception is a more informative; therefore, I'd try to avoid just returning an empty string at the end, because it's not semantically explaining that calling rmstr(array, object) returns an empty string.
My opinion is that you should perform such verification if you are accepting input from the user. If those strings were not accepted from the user or are sanitized input from the user, then doing verification there is excessive.
As for me, type checking actual to data, getted from user on top level of abstraction, but after that, when You call most of your functions you already should now their type, and don't check it out in every method. It affects performance and readability.
Note: you can add info, which types is allowed to arguments for your functions by phpDoc
It seems local folks understood this question as "Should you verify parameters" where it was "Should you verify parameter types", and made nonsense answers and comments out of it.
Personally I am never checking operand types and never experienced any trouble of it.
It depends which code you produce. If it's actually production code, you should ensure that your function is working properly under any circumstances. This includes checking that parameters contain the data you expect. Otherwise throw an exception or have another form of error handling (which your example is totally missing).
If it's not for production use and you don't need to code defensively, you can ignore anything and follow the garbage-in-garbage-out principle (or the three shit principle: code shit, process shit, get shit).
In the end it is all about matching expectations: If you don't need your function to work properly, you don't need to code it properly. If you are actually relying on your code to work precisely, you even need to validate input data per each unit (function, class).

Categories