When you leave a variable expansion unquoted, it undergoes word splitting and filename expansion (i.e. globbing). It isn't parsed as a shell command. In general, when you dynamically construct a shell snippet to execute, the right way to execute it is
eval "$a" where
a contains the string to parse as shell code.
In your first snippet, the value of
a is the string
my_cmd --verbose. Word splitting breaks it into two words
--verbose. Globbing does nothing since there are no wildcards in any of the words. The command resulting from the expansion of
$a thus consists of two words
--verbose, so the command
my_cmd (which could be an alias, a function, a builtin or an executable in the PATH) is executed with the single argument
In the second snippet, things are similar, with three words resulting from the expansion:
--verbose. This results in an attempt to execute the command
URL=myurl with two arguments.
The shell command
URL=myurl my_cmd --verbose is parsed differently: the first word is parsed as an assignment to the variable
URL, and since there is a command name after it the assignment sets the environment variable for the duration of the command only. This is part of parsing, not something that's done after expansion, so it requires the equal sign to be part of the shell source code, the equal sign can't be the result of some expansion.
Don't store a command with parameters into a string. Use an array. For a complex command, such as one where you set variables or perform redirection in addition to running the command, use a function if at all possible, and if not use
eval (taking great care of proper quoting).