I want to use all strings and array as an object where we can add our functions.
<?php
// Str class
class Str {
private $str;
public function __construct($str) {
$this->str = $str;
}
public function len() {
return strlen($this->str);
}
public function md5() {
return new static(md5($this->str));
}
public function __toString() {
return $this->str;
}
}
// to cast string into str object
function str($str) {
return new Str($str);
}
// casting string to str object
$str = str("Hello World");
echo $str;
// output: Hello World
echo $str->len();
// output: 11
echo $str->md5()->md5();
// output double md5 of string 'Hello World'
I want to know if it is a good idea to implement this in my high end application. I will add all string functions with my own custom functions to this Str class.
Will it consume too much memory?
Will I encounter any performance issues?
Interesting idea. Resembles JavaScript's String function/object/constructor due to the prototype methods. I've done similar stuff in the past and it didn't have any memory or performance issues. You might want to take advantage of magic methods such as __toString() (which I see you're already doing), as well as __call() and __callStatic(). Also a good idea to add implements Serializable. With some cleverness, you can have a pretty functional class. Although I'd sooner use a string literal since such an implementation wouldn't really offer anything functionality-wise. But if you can think-up a useful implementation, perhaps to build some sort of JavaScript engine, you can start with a top-most class maybe JSObject, then rename your class to maybe JSString and extend it, and also have JSArray and JSDate etc. I'd be interested if you can implement a JavaScript-like environment, with inheritance and all, in PHP. Sounds like a fun side-project to work on, but I can't really think of a practical usage for it. But in terms of expanding your PHP knowledge, and mastering it, I think it's a good learning opportunity to see for yourself PHP's limitations. Push PHP's limitations to the limit and you might learn something. If you decide to go this route, there's 2 more magic methods you can have a load of fun with. __get() and __set(). This way you can just call, for example, $myString->length or $myObject->key="value" and have it stored into an internal array allowing you to easily preform manipulations on the data whenever it changes etc. Just make sure to define a __isset() method if you decide to define dynamic properties. See also: http://php.net/manual/en/reserved.interfaces.php
Edit:
Perhaps a useful implementation would be the ability to define a hierarchy structure such as how many sites have to manage categories/subcategories and the number of products in each category. Such an implementation would allow you to easily define such a hierarchy structure without having to worry about children or number of children or grandchildren etc. But even still, not so practical since I'd sooner just use recursive function to walk such a hierarchy structure. Perhaps a more practical implementation would be an HTML parser of some sort. But this is re-inventing the wheel, although good practice. What I do know, though, is that many PHP frameworks out there take advantage of the above-mentioned features to implement MVC environments. So if you think you can build a better framework than ones already existing, or some other related environment aimed at coders, perhaps that would be the most practical implementation of the above mentioned features.
No,it will not consume too much memory.Also,you don't get any performance issues instead of its reusable across your application.
Related
I'm reading the new features of PHP7 and this doubt comes to me with this one:
Returning values: Return type declarations
function sum($a, $b): float {
return $a + $b;
}
// Note that a float will be returned.
var_dump(sum(1, 2));
The only purpose I can find is to be more specific in interface definition (which is an advantage). But, is there any other reason of including them in every method?
If you're writing a library for other code to consume, it's good to have a well-defined API, and declared return types are part of that. It saves people having to ferret around in the source code to work it out.
For your own code usage, it's a safety check that you're writing your function correctly, and staying "on plan". It encourages your functions to do one thing, and to stay focused. PHP itself is a bit of a mess in places where it has functions which might return an integer value or a boolean if something didn't go according to plan. This is pretty terrible coding. It means the calling code has to code for both eventualities, which it shouldn't need to do. If you specify a return type on your function, you'll not be able to go down that route.
Also as others have said, it helps your IDE to work out what's supposed to be going on as well. That's handy. IDEs will also leverage those phpdoc annotation comments, but they're comments so they lie, and don't actually enforce a contract, so aren't really... a good thing.
Is using an instance of a class to access static methods considered bad practice?
I.e.
$model = new MyClass();
$options = MyClass::getOptions();
vs
$model = new MyClass();
$options = $model::getOptions();
($model is instantiated in either case, I'm just wondering if one approach is preferable to the other.)
Traditionally the first way (specifying the class name itself) has more similarities with other languages such as Java.
The second one is unique to PHP (afaik); it works because the :: operator disambiguates the expression, unlike Java where a period is used for both instance and static properties.
I'm not sure what the performance impact is by using the second option, but I think it comes down to personal taste / coding standards.
Conclusion
If the types of your instances are immediately clear from the surrounding code it might be easier to go for the second option (sometimes the class name can be pretty big); but if not, use the first option as it's the most explicit.
That depends, I think. You can happily use static methods for many happy years, enjoying instantiation-free code, but one day you'll have to reroute some (that's where it goes) calls to another, descendant class, so simple search-and-replace call won't do. ) So going with a prepared object is a safer route, I think.
As an alternative, you can use something like this:
$className = 'MyClass';
$className::classyMethod1();
$className::classyMethod2();
... but that may become pretty confusing with time, I suppose (and is usable only in PHP 5.3+)
I believe, this alternative:
$options = MyClass::getOptions();
actually is wasting less memory, because you aren't needing a extra variable to call the static function.
I'm wondering what you think the best practice is here-- does it buy you very much to type-check parameters in PHP? I.e have you actually seen noticeably fewer bugs on projects where you've implemented parameter type-checking vs. those that don't? I'm thinking about stuff like this:
public function __construct($screenName, $createdAt) {
if (!is_string($screenName) || !is_string($createdAt) {
return FALSE;
}
}
Normally within a PHP application that makes use of the skalar variable "types" is bound to actually string input (HTTP request). PHP made this easier so to convert string input to numbers so you can use it for calculation and such.
However checking scalar values for is_string as proposed in your example does not make much sense. Because nearly any type of variable in the scalar family is a string or at least can be used as a string. So as for your class example, the question would be, does it actually make sense to check the variable type or not?
For the code you proposed it does not make any sense because you exit the constructor with a return false;. This will end the constructor to run and return a not-properly-initialized object.
Instead you should throw an exception, e.g. an InvalidArgumentException if a constructors argument does not provide the expected / needed type of value.
Leaving this aside and taking for granted that your object constructor needs to differ between a string and an integer or bool or any other of the scalar types, then you should do the checks.
If you don't rely on the exact scalar types, you can cast to string instead.
Just ensure that the data hidden inside the object is always perfectly all-right and it's not possible that wrong data can slip into private members.
It depends. I'll generally use the type-hinting that is built into PHP for higher-level objects ((stdClass $obj, array $arr, MyClass $mine)), but when it comes to lower level values -- especially numbers and strings, it becomes a little less beneficial.
For example, if you had the string '12345', that becomes a little difficult to differentiate between that and the number 12345.
For everything else, the accidental casting of array to a string will be obvious. Class instances which are cast to strings, if they don't have a __toString, will make PHP yell. So your only real issue is classes which have a __toString method and, well, that really limits the number of times where it can come up. I really wonder if it is worth that level of overhead.
Checking function arguments is a very good practice. I suspect people often don't do that because their functions grow bigger and the code becomes uglier and less readable. Now with PHP 7 you can type-hint scalar types but there is still no solution for cases when you want your parameter to be one of two types: array or instance of \Traversable (which both can be traversed with foreach).
In this case, I recommend having a look at the args module from NSPL. The __constructor from your example will have the following look:
public function __construct($screenName, $createdAt)
{
expectsAll(string, [$screenName, $createdAt]);
}
// or require a non-empty array, string or instance of \ArrayAccess
function first($sequence)
{
expects([nonEmpty, arrayAccess, string], $sequence);
return $sequence[0];
}
More examples here.
Better documentation is more important when you're the only one interacting with the methods. Standard method definition commenting gives you well documented methods that can easily be compiled into an API that is then used in many IDEs.
When you're exposing your libraries or your inputs to other people, though, it is nice to do type checking and throw errors if your code won't work with their input. Type checking on user input protects you from errors and hacking attempts, and as a library letting other developers know that the input they provided is not what you're expecting is sometimes nice.
I am not really clear about declaring functions in php, so I will give this a try.
getselection();
function getselection($selection,$price)
{
global $getprice;
switch($selection)
{
case1: case 1:
echo "You chose lemondew <br />";
$price=$getprice['lemondew'].'<br>';
echo "The price:".$price;
break;
Please let me know if I am doing this wrong, I want to do this the correct way; in addition, php.net has examples but they are kind of complex for a newb, I guess when I become proficient I will start using their documentation, thank you for not flaming.
Please provide links that might also help me clear this up?
Your example seems valid enough to me.
foo('bar');
function foo($myVar)
{
echo $myVar
}
// Output: bar
See this link for more info on user-defined functions.
You got off to a reasonable start. Now all you need to do is remove the redundant case 1:, close your switch statement with a } and then close your function with another }. I assume the global array $getprice is defined in your code but not shown in the question.
it's good practice to declare functions before calling them. It'll prevent infrequent misbehavior from your code.
The sample is basically a valid function definition (meaning it runs, except for what Asaph mentions about closing braces), but doesn't follow best practices.
Naming conventions: When a name consists of two or more words, use camelCase or underscores_to_delineate_words. Which one you use isn't important, so long as you're consistent. See also Alex's question about PHP naming conventions.
Picking a good name: a "get" prefix denotes a "getter" or "accessor"; any method or function of the form "getThing" should return a thing and have no affects visible outside the function or object. The sample function might be better called "printSelection" or "printItem", since it prints the name and price of the item that was selected.
Globals: Generally speaking, globals cause problems. One alternative is to use classes or objects: make the variable a static member of a class or an instance member of an object. Another alternative is to pass the data as an additional parameter to the function, though a function with too many parameters isn't very readable.
Switches are very useful, but not always the best choice. In the sample, $selection could easily hold the name of an item rather than a number. This points to one alternative to using switches: use an index into an array (which, incidentally, is how it's done in Python). If the cases have the same code but vary in values used, arrays are the way to go. If you're using objects, then polymorphism is the way to go--but that's a topic unto itself.
The $price parameter appears to serve no purpose. If you want your function to return the price, use a return statement.
When you called the function, you neglected to pass any arguments. This will result in warnings and notices, but will run.
I'm looking to improve my PHP coding and am wondering what PHP-specific techniques other programmers use to improve productivity or workaround PHP limitations.
Some examples:
Class naming convention to handle namespaces: Part1_Part2_ClassName maps to file Part1/Part2/ClassName.php
if ( count($arrayName) ) // handles $arrayName being unset or empty
Variable function names, e.g. $func = 'foo'; $func($bar); // calls foo($bar);
Ultimately, you'll get the most out of PHP first by learning generally good programming practices, before focusing on anything PHP-specific. Having said that...
Apply liberally for fun and profit:
Iterators in foreach loops. There's almost never a wrong time.
Design around class autoloading. Use spl_autoload_register(), not __autoload(). For bonus points, have it scan a directory tree recursively, then feel free to reorganize your classes into a more logical directory structure.
Typehint everywhere. Use assertions for scalars.
function f(SomeClass $x, array $y, $z) {
assert(is_bool($z))
}
Output something other than HTML.
header('Content-type: text/xml'); // or text/css, application/pdf, or...
Learn to use exceptions. Write an error handler that converts errors into exceptions.
Replace your define() global constants with class constants.
Replace your Unix timestamps with a proper Date class.
In long functions, unset() variables when you're done with them.
Use with guilty pleasure:
Loop over an object's data members like an array. Feel guilty that they aren't declared private. This isn't some heathen language like Python or Lisp.
Use output buffers for assembling long strings.
ob_start();
echo "whatever\n";
debug_print_backtrace();
$s = ob_get_clean();
Avoid unless absolutely necessary, and probably not even then, unless you really hate maintenance programmers, and yourself:
Magic methods (__get, __set, __call)
extract()
Structured arrays -- use an object
My experience with PHP has taught me a few things. To name a few:
Always output errors. These are the first two lines of my typical project (in development mode):
ini_set('display_errors', '1');
error_reporting(E_ALL);
Never use automagic. Stuff like autoLoad may bite you in the future.
Always require dependent classes using require_once. That way you can be sure you'll have your dependencies straight.
Use if(isset($array[$key])) instead of if($array[$key]). The second will raise a warning if the key isn't defined.
When defining variables (even with for cycles) give them verbose names ($listIndex instead of $j)
Comment, comment, comment. If a particular snippet of code doesn't seem obvious, leave a comment. Later on you might need to review it and might not remember what it's purpose is.
Other than that, class, function and variable naming conventions are up to you and your team. Lately I've been using Zend Framework's naming conventions because they feel right to me.
Also, and when in development mode, I set an error handler that will output an error page at the slightest error (even warnings), giving me the full backtrace.
Fortunately, namespaces are in 5.3 and 6. I would highly recommend against using the Path_To_ClassName idiom. It makes messy code, and you can never change your library structure... ever.
The SPL's autoload is great. If you're organized, it can save you the typical 20-line block of includes and requires at the top of every file. You can also change things around in your code library, and as long as PHP can include from those directories, nothing breaks.
Make liberal use of === over ==. For instance:
if (array_search('needle',$array) == false) {
// it's not there, i think...
}
will give a false negative if 'needle' is at key zero. Instead:
if (array_search('needle',$array) === false) {
// it's not there!
}
will always be accurate.
See this question: Hidden Features of PHP. It has a lot of really useful PHP tips, the best of which have bubbled up to the top of the list.
There are a few things I do in PHP that tend to be PHP-specific.
Assemble strings with an array.
A lot of string manipulation is expensive in PHP, so I tend to write algorithms that reduce the discrete number of string manipulations I do. The classic example is building a string with a loop. Start with an array(), instead, and do array concatenation in the loop. Then implode() it at the end. (This also neatly solves the trailing-comma problem.)
Array constants are nifty for implementing named parameters to functions.
Enable NOTICE, and if you realy want to STRICT error reporting. It prevents a lot of errors and code smell: ini_set('display_errors', 1); error_reporting(E_ALL && $_STRICT);
Stay away from global variables
Keep as many functions as possible short. It reads easier, and is easy to maintain. Some people say that you should be able to see the whole function on your screen, or, at least, that the beginning and end curly brackets of loops and structures in the function should both be on your screen
Don't trust user input!
I've been developing with PHP (and MySQL) for the last 5 years. Most recently I started using a framework (Zend) with a solid javascript library (Dojo) and it's changed the way I work forever (in a good way, I think).
The thing that made me think of this was your first bullet: Zend framework does exactly this as it's standard way of accessing 'controllers' and 'actions'.
In terms of encapsulating and abstracting issues with different databases, Zend_Db this very well. Dojo does an excellent job of ironing out javascript inconsistencies between different browsers.
Overall, it's worth getting into good OOP techniques and using (and READING ABOUT!) frameworks has been a very hands-on way of getting to understand OOP issues.
For some standalone tools worth using, see also:
Smarty (template engine)
ADODB (database access abstraction)
Declare variables before using them!
Get to know the different types and the === operator, it's essential for some functions like strpos() and you'll start to use return false yourself.