Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Hi,
is it possible to set the value of a variable that is an array using vset? Or is there an elegant solution to solve this problem?
$ drush vget foo
foo: Array
(
[bar] => 1
)
$ drush vset foo ??????
Comment | File | Size | Author |
---|---|---|---|
#4 | drush_variable-set_serialized_values.patch | 534 bytes | apotek |
Comments
Comment #1
moshe weitzman CreditAttribution: moshe weitzman commentedNot currently possible. For now, I think you want to use eval(variable_set()) or script command.
We could conceivably support incoming array via our JSON REST API. Not sure that would be useful in practice. Feedback welcome.
Comment #2
apotek CreditAttribution: apotek commentedI originally posted this at #3141794, but then saw this feature request, and decided it was more appropriate here.
+1 for support for setting a variable within a serialized value. If the variable setting is a serialized array, and you want to change one member of the array, it's pretty tough to parse and set accurately via shell. I see you can pipe it out with --pipe and let cli php handle it. Is that the recommended approach, something like?
Don't try this. it doesn't work quite, as drush interprets the value as a plain string, not an string representing a serialized array in variable-set. My point is simply that this is obviously *extremely* brittle, even if I *could* get this to work through some shell/php trickery.
My proposal would be to extend variable-set with
$ drush variable-set varname[arraymember] setting
This would handle setting members of arrays, and
$ drush variable-set varname->propertyname settings
Would handle setting properties of any objects stored in the variables table (don't know of any). The idea would be to parse the first param (varname or varname[arraymember] or varname->propertyname) to see whether to handle it as a literal, array or object.
Comment #3
apotek CreditAttribution: apotek commentedAnother way to handle this would be to use the terribly brittle approach, piping to shell, etc, but then simply parse the incoming string not just for string versus int, but whether it starts with
Not nearly as robust as the proposal above, but would be a quicker fix.
Or, better than parsing the first characters would be checking if incoming value is unserializable...
Happy to contribute this as a patch if anyone thinks it's worth it.
Comment #4
apotek CreditAttribution: apotek commentedHere's a 5 line patch to variable.drush.inc that allows for setting values as serialized arrays or objects.
Unfortunately it still relies on horrendous amounts of shell work, but it is a workaround.
Of course, this is only gonna work as long as there are no single-quotes in the contents of the serialized array or object.
Comment #5
greg.1.anderson CreditAttribution: greg.1.anderson commentedDon't like it; too much shell work, too fragile. It's a start in the right direction, though.
Comment #6
apotek CreditAttribution: apotek commentedSo what do you think of my proposal at the bottom of my comment #2?
Comment #7
greg.1.anderson CreditAttribution: greg.1.anderson commentedWhat if the user was trying to set an array with seven members? What if the user only specified three of the members; are the other array values set to zero, or preserved without change? What if you write a script that assumes the array has seven members, and then a new version of Drupal or the Drupal module comes out, and an eighth member is added?
It seems to me that a syntax more in line with JSON encoding is what's needed here; the problem is that structures like that are really hard to enter from the command line.
When dealing with arrays, it might be better to just use
drush script
. Then you can express exactly what you mean in code.Comment #8
greg.1.anderson CreditAttribution: greg.1.anderson commentedI just re-read moshe's comment in #1. Shall we just set this to "won't fix"?
Comment #9
gbell12 CreditAttribution: gbell12 commentedOK now that we have the workaround, can someone please provide an example of how to use
drush script
to set an array?Comment #10
moshe weitzman CreditAttribution: moshe weitzman commentedComment #11
techgirlgeek CreditAttribution: techgirlgeek commentedInterested in this as well.
Comment #12
msonnabaum CreditAttribution: msonnabaum commentedThis came up in IRC again today. I think we should have vget accept json via STDIN and give vset the "format" option so it can output json. We already do this on cache-get/set.
Basically, I don't think the difficulty of entering it on the cli is relevant. Let's assume its being outputted from another command.
Comment #13
anarcat CreditAttribution: anarcat commentedThe way to pass stuff through stdin/stdout/JSON is usually --backend. Unfortunately, drush vget --backend doesn't include the variables anywhere else than as a string in the "output" variable. vget would need to set something somewhere so they would be exported, and do the same with vset. Maybe that's already the case...
Comment #14
greg.1.anderson CreditAttribution: greg.1.anderson commentedIf vget just returns the variables in an array (as the function result), then it will be put into the 'object' item of the backend invoke results.
Comment #15
moshe weitzman CreditAttribution: moshe weitzman commentedI just committed #14. It may not be that helpful here, but it is generally a good thing.
Comment #16
suffusionofyellow CreditAttribution: suffusionofyellow commentedif running from the shell directly, remember to protect variable names i.e.:
drush ev "\$a=variable_get('gmap_default');\$a[markermode]='1';variable_set('gmap_default',\$a);"
Comment #17
greg.1.anderson CreditAttribution: greg.1.anderson commentedI prefer to write #16 as:
It's easier to not have to think about backslashing every $, but I have to admit, I sometimes mess up and type
'
instead of"
when I'm doing this.Comment #18
moshe weitzman CreditAttribution: moshe weitzman commentedComment #19
moshe weitzman CreditAttribution: moshe weitzman commented#12 sounds good to me.
Comment #20
moshe weitzman CreditAttribution: moshe weitzman commentedCommitted json support as input and output format.
Comment #21
kenorb CreditAttribution: kenorb commented+1
Comment #22
moshe weitzman CreditAttribution: moshe weitzman commentedWon't apply cleanly. Needs reroll.
Comment #23
boombatower CreditAttribution: boombatower commentedsub, this would help me out
Comment #24
rfayCould we please have an issue summary explaining how this actually works? Very difficult to parse the comments here. Just an example will do. drush help vset offers
But a simple example of setting an array would be so much better.
Comment #25
rfayHere's an example with a simple array:
Comment #26
moshe weitzman CreditAttribution: moshe weitzman commentedCommitted the new example to master in 5e6f49b
Comment #27
Michael-IDA CreditAttribution: Michael-IDA commentedJust FYI for those with a standard drush install (currently drush version 4.5), trying to set an array per example in #25 will destroy the variable for drush.
You can successfully set/change the variable through /admin/config/system/site-information, but drush still shows the corrupted variable:
# # #
So, when is drush 5.x going to be production worth?
Best,
Sam
Comment #28
msonnabaum CreditAttribution: msonnabaum commentedSince this is new functionality I'd rather not backport it into 4.x. Someone can reopen with a patch if they feel strongly about it.
Comment #30
dhaval_panara CreditAttribution: dhaval_panara commentedAny buddy know why we are using hyphen sign (-) in last. Is there any difference if we are not using it?
For example : php -r "print json_encode(array('drupal', 'simpletest', 'leftandright', 'category'));" | drush vset --format=json project_dependency_excluded_dependencies -
Comment #31
helmo CreditAttribution: helmo commented@dhaval_panara The hyphen indicates that the new value should be read from stdin
Comment #32
dhaval_panara CreditAttribution: dhaval_panara commented@helmo Thanks....