Why does WP_Query have methods that return public properties of the same name

While your example of is_search() is a rather trivial one and harder to justify, it’s generally recommended in OOP styles to use getters and setters for things like this instead of public properties, for a number of reasons.

  • Encapsulation. The behavior of is_search() returns a boolean, but the method by which it determines whether or not a search is taking place could change in the future. Right now, the is_search variable is set earlier in the process and then this function returns it. A later version might do an immediate check to see if the current URL is a search one instead, depending on how the template system changes. For example, the property, though public, might change later. Right now it’s stored as a boolean, but maybe something like “search_string” could be checked instead and a boolean then returned by is_search(). The output by the function hides the internal state of the variables being used, because the outside doesn’t need to know those necessarily.

  • Public methods like is_search() are your interface, and the interface can thus remain more constant over time. Better to use something that’s less likely to change (is_search() is only ever going to return a boolean, realistically).

  • Lots of other libraries and development systems know about getters and setters and work better when they exist. It’s a common style choice, best to fit the mold.

  • Classes that inherit from your class can change how the fundamental basics work, and these functions allow them to use these to override behavior. Having to keep variables public and modify them internally is more difficult and error prone.

  • Functions, even object methods, can be passed around as callbacks to things like filter functions and such. Variables can’t.

So, the real answer to your question is that the is_search variable probably should not be public. The method existing is relatively normal.

When coding, code defensively. Even if you can access the is_search variable directly, use the is_search() function instead. If the variable changes at all in the future, the function will change to accommodate it and still give you the correct output.