Yes. Every place I stated this included that it was an array and your previous code above used an array (the  is short-cut syntax for an array.) For the case where you weren’t using an array, you should have been getting a php error. Do you have php’s error_reporting set to E_ALL and display_errors set to ON so that php would help you by reporting and displaying all the errors it detects? These two settings should be in the php.ini on your system so that all errors will be reported. Stop and start your web server to get any changes made to the php.ini to take effect.
In most cases you should just let php catch and handle the error (you would not have a try/catch block in your code) where it will use its error_reporting, display_errors, and log_errors settings to control what happens with the actual error information. When learning, developing, and debugging code/queries you should display all errors (see the settings mentioned above.) When on a live/public server, you should log all errors (by changing the display_errors setting to OFF and the log_errors setting to ON.) For a data driven design, most database errors are fatal and there’s no point in doing more than displaying/logging the error and halting execution (which will all happen automatically if you let php catch and handle the exception.) The exception to this is when you are inserting/updating user supplied data and a duplicate value error occurs. This is a recoverable application error. In this case you would have a try/catch block around the execution of the query, detect if the error number is for a duplicate key error (requires defining the data column(s) as a unique index), set up a user error message telling the user what was wrong with the data that was submitted, and continue program execution. If the error is not for a duplicate key, re-throw the exception and let php handle it.
See the error_reporting, display_errors, and log_errors settings mentioned in this reply.
The genera table you have in your example is the ‘defining’ table for the genera values. In addition to providing language translation, it should have an id (auto-increment) column that establishes a genera_id. You would also have defining tables for the other major taxonomic categories - Kingdom, Phylum, Class and Species. When you store data for each actual organism, you would use the ids established in these defining tables. To retrieve data, you would use a JOIN query to get the related values form the different tables.
There are two main reasons for using a prepared query -
To prevent sql special characters in external/unknown data from breaking the sql query syntax (which is how sql injection is accomplished.)
To save the time needed to communicate the sql query statement between php and the database server and the parsing and planning time of the sql query on the database server, when executing a query more than once during a single invocation of your script.
If an sql query has external/unknown data being supplied to it (executed once or multiple times with the same or different input values) use a prepped query. In those few cases where you need to execute an sql query, that doesn’t have any external/unknown data, more than once in a single invocation of your script, use a prepared query. Otherwise, use the ->query() method.
An issue with emulated prepared queries or using the PDO quote() method in your code is, if you haven’t set the character set that php is using to match the character set of your database tables, sql injection is still possible. Also, the emulation isn’t accurate, so there are functional differences between emulated and true prepared queries.