Jump to content

gizmola

Administrators
  • Posts

    5,878
  • Joined

  • Last visited

  • Days Won

    139

Everything posted by gizmola

  1. In phpMyAdmin, when you look at the list of tables for a database the "type" column shows you the engine. If you did not explicitly set the engine to use the InnoDB engine you will likely have all tables using the default MyISAM engine. You'll need to alter that for each table using a SQL statement: ALTER TABLE TableName ENGINE = InnoDB; MyISAM is not ACID compliant. It also will have thrown away any foreign key constraints, so if you had or wanted those you'd need to recreate them individually after you altered the tables to use InnoDB. Correct. For InnoDB tables. What that means from a performance standpoint, is that if there's a query that uses the primary key index, the entire data for the row gets read in the same operation that searched the index. I only bring this up since you asked about performance, and is one of the many reasons that MySQL DBA's are fairly unanimous in favoring the use of InnoDB.
  2. If your structure is normalized correctly you should be fine. Make sure that your tables are using the InnoDB engine. Any queries that can be satisfied by using the primary key index return all data in the record by reading the index itself. This is because InnoDB has "clustered indexes" which is a fancy term meaning that the data is actually stored in the primary key index. All primary and foreign keys are inherently indexed. So the main concern in regards to other required indexes would be queries that have where clauses that aren't keys in the table definition. This is the single most important detail. Your queries need to use a relevant index. An obvious example would be username & password columns in a user table. Essentially you just need to focus on the WHERE clauses of your queries and make sure that you have an index to handle the query. For example, if you always query for user by username & password, have an index on username, password, and not individual indexes on username and password. If you have a monolithic server (webserver, php, mysql running on one box) then you have to plan for contention. MySQL needs some tweaking to provide a sufficient InnoDB buffer pool allocation. If it's a small DB as you describe your entire dataset can be in the buffer pool cache the majority of the time.
  3. Probably one of the most common misunderstanding for people starting out with the concept of "seo friendly" url's. You are definately not alone, but kuddos for figuring it out on your own.
  4. Phi11w provided an excellent and thorough analysis. In particular consider this data for $admin: <?php $admin = ['fullname' => 'Sally Smith', 'gender' => 'F']; function getAdminName() { global $admin; return ( $admin['gender'] ? 'Mr' : 'Mrs') . ' ' . $admin['fullname'] ; } echo getAdminName(); Do you get what you would expect for a gender 'F' person named 'Sally Smith'? While all of Phi11w's points are valid, I think this is the main thrust of the issue. Even without knowing the scheme to be used, it is unlikely that gender would be a boolean value. Another issue being glossed over, is that 'Mrs' has the connotation of marriage, as well as Barand's point about 'Dr' and other sultations, but that makes things more complicated, and I don't think that was factored into the question, because the existing code has an obvious data typing issue. So an improved function (assuming php7): <?php $admin1 = ['fullname' => 'Sally Smith', 'gender' => 'F']; $admin2 = ['fullname' => 'Randy Jones', 'gender' => 'm']; $admin3 = ['fullname' => 'Pat Samuels']; function getAdminName($admin) { $admin['fullname'] = trim($admin['fullname']) ?? 'unknown'; $admin['gender'] = $admin['gender'] ?? ''; $pre = ''; switch (strtolower($admin['gender'])) { case 'f': $pre = 'Mrs '; break; case 'm': $pre = 'Mr '; break; default: $pre = ''; } return $pre . $admin['fullname']; } echo getAdminName($admin1) . PHP_EOL; echo getAdminName($admin2) . PHP_EOL; echo getAdminName($admin3) . PHP_EOL;
  5. First query, as ginerjm pointed out: SET status = ?, comment = ?, department = ? WHERE id = ? Four '?' , but your bind string is 'ssi'
  6. Another valuable free tool that can be used to test your serverside api calls is Postman. Here's an introduction video I scanned that can teach you the basics of using it effectively in a short amount of time. There are complete courses available on Youtube that cover all aspects of using it, but for your purposes, an investment of 30 minutes or less should have you up and running and testing your login.php script independently from the Unity client code.
  7. Absolutely. The primary options for getting up to date versions of php and the various extensions are: Extra Packages for Enterprise Linux (EPEL) Remi's RPM Repo I have used one or both at various times over the years. One other Repo that has had a focus on PHP is https://ius.io/. The other option is to run your setup in containers using Docker/Kubernetes/rkt etc.
  8. I'm fine with disabling replies. It fits our intentions perfectly. Only thing it doesn't allow is the poster to reply to the original post stating the opportunity is filled, but people rarely if ever have done that anyways. The constant flow of dummies who don't read the instructions and reply anyways is annoying.
  9. Wordpress is going to run under/through the webserver. There are many ways to configure this, whether it be apache/mod_php, or nginx/php-fpm, or apache/php-fpm etc. We would need more information on your webserver and it's configuration. Did you try to make a simple phpinfo() file in the root directory of your wordpress install? Are there any other php apps setup to run on this server? Step 1: make a test file: // test.php <?php phpinfo(); Navigate to this and report back the results. Step2: Provide details on the web server and php configuration. Double check the php specific parts of this configuration Step3: Provde this information from your shell: sudo rpm -qa | grep php
  10. Along the lines of what requinix stated, here are some functions you'll need to calculate where to place your text: imagefontwidth imagefontheight imagesx imagesy To get the length of the string, you need to find imagefontwidth($font) * strlen($yourtext). Hopefully it's fairly obvious that your x,y coordinate for writing the string is going to be: y = imagesy() - (imagefontheight + padding) x = imagesx() - (imagefontwidth($font) * strlen($yourtext) + padding)
  11. I agree with requinix. Newbies really love the facades, but then when they start writing unit tests they are quickly sorry they did. In comparing the 2 frameworks: Laravel is opinionated and comes with things like a user system. Symfony isn't, but does have bundles from groups like "Friends of Symfony" aka FOS, who have a symbiotic relationship with the main Symfony project. There's a large number of FOS bundles you can drop into your Symfony project like the FOS User Bundle and Rest Bundle which might be of specific value to your project. Laravel has an Active Record ORM for database models called Eloquent, that includes a query builder and is solid. Symfony does not provide an ORM, but again has a long relationship both with the Propel and Doctrine projects. Doctrine provides a Data Mapper pattern implementation, which I greatly prefer to Active Record, and it also comes with "Repositories" and a connection manager that handles persistence and transactions in a superior way. The sophistication of the behavior available in Doctrine is far more advanced than what Eloquent offers. Routing and Controllers are comparable in each. Laravel's template language Blade is ok. Symfony's Twig is more advanced in its abilities to compose templates from partials and inheritance. Laravel comes with pretty much everything you need out of the box to develop most types of projects, and has a fair amount of "magic" that handles making everything work together. It's an excellent project with a large community and documentation galore. It's also very popular, and probably has more adoption than Symfony does, particularly in many parts of the US. Symfony also has a large community, and out of that community not only did Laravel emerge, but also Composer, which was an essential dependency management tool that in my opinion saved PHP from obscurity as a web development platform. Having done large projects with both frameworks, I would still choose Symfony (with Doctrine and Twig), but really either one will work for you. They are both dependency injection frameworks, and have a dependency injection container and ways to configure services based on class libraries, whether those be ones you get from FOS or other sources, or that you have built yourself.
  12. Did you try an explain on the underlying query? It might be good to see if an additional index or 2 might help with performance.
  13. Hey Saranac, You seem to be conflating a "transaction" which is a database specific term, with a single page application (SPA) or combined form. What you do serverside with that form is up to you. Ease of use, credit card/payment processing and the dangers and cost of fraud are a complicated witches brew of risk/reward calculations. First of all, I don't know what you know or don't know about payment processing, but just because you got a cc authorization doesn't mean you will ever get paid. Worse yet, you could get a chargeback, and if you have enough chargebacks, you might end up having your merchant account closed. Again, maybe you know this or you don't. I don't know what your content is, or whether or not there will be a high amount of fraudulent activity, but every online business has some. So, as to transactions, and to "best practices" for selling digital goods or memberships, these topics are unrelated. At its simplest, a Member in your system, as you stated yourself, is not equivalent to a membership package. Membership packages also have one or more related "entitlements". So no doubt you have a package described in the database somewhere, and when someone successfully subscribes to a package for a year, one would expect a database structure like this: package ---< member_package >-- member where member_package is a table that stores "member_id", "package_id", "from_date", "to_date". What are strategies for dealing with the system. Well one, would be to have the culmination of a successful payment process be the setting of the "from_date" and "to_date". Another strategy might be to also utilize a "status" column with mutually exclusive states like: pending payment active suspended for fraud expired In that case you create the row, and can then use "active" status to drive access (along with from/to). Regardless of the form you use, there is no benefit to wrapping the creation of a member row with the transaction processing. If a member fills out all their details and has payment processing issues, it behooves you to create the membership row and put them into "pending payment" state. This way you can see how many people had issues with payment processing at any particular period of time. That way you can reach out to people who for whatever reason drop out of the payment process. You have contact info to market to them, or entice them with discounts. And there is always the situation where your payment processor was rejecting everything and these are customers you have 100% lost forever without some record that they tried to subscribe. DB transactions are important from a mechanical standpoint and I highly recommend using them, but you can have multiple transactions in your processing ie (membership account + address) THEN (payment processing & activation) and these can be handled separately in your code. Once you have some identity information, it's valuable to continue to carry this along in your session rather than stubbornly demand that the behavior of your system should conform to your ideal "happy path" scenario where a user puts in all their identity information for their membership perfectly, and at the same time gets the payment information entered perfectly and receives authorization. A "member" row, should be decoupled from membership (which you already stated you understand and agree with) which should be decoupled from subscription(s) which should be decoupled from payment processing details.
  14. Hey Paul-D, Quick clarification: Solaris is not Linux. It's the long standing Sun Unix designed to run on Sun Sparc hardware. Sun was bought by Oracle which is why you can get it from Oracle now. I would not recommend going down that road. Linux has many flavors, but it sound like what you want is a distribution that aims to provide a Desktop environment. Another thing you need to understand about a Linux distro is how committed they are to Free Open Source Software (FOSS). Some distros (for philosophical reasons) will not include or package any non FOSS software, which sometimes means that you have to do a lot of work yourself to get certain drivers or software that you might want or need in your Desktop environment. Linux OS's are in a constant state of flux and new distro's appear regularly. I'll boil down my highly opinionated list for you, with the assumption that you are new to linux, and want a Desktop Linux that looks modern, has package management tools, and is focused on ease of installation, use and configuration. Elementary - Focused on users switching from Mac or PC, this distro has gained a lot of momentum in a short amount of time as an opinionated simple to install OS Zorin OS - Like Elementary a recent entry in the Desktop Windows/Mac replacement distros, with a particular focus on being friendly to former Windows users Pop!_OS - Another of the newer Desktop focused distro's. Comes from System76, which is a Unix hardware vendor that designs and sells everything from laptops and desktops to rackmountable servers. Ubuntu - The longstanding "beginner focused" Debian variant has done a lot to further the goals of Desktop Linux for the masses. I ran it myself for a few years at work. Fedora - This is Redhat's project that has long provided a Desktop OS. Opensuse - Like Fedora, OpenSuse is another of the longstanding linux Desktop focused distros. It has YaST and Zypper for GUI configuration. I have not tried it myself, but many linux Sysadmins have sworn by it for years. I don't know if you listen to Podcasts, but Choose Linux covered many of these OS's to some degree in the first 11 episodes of the podcast. The episodes are fairly short, so you might want to listen to a few of them if a particular distro on this list appeals to you.
  15. Symfony or Laravel, with a strong endorsement of the latest Symfony (v5).
  16. Good luck to you on that Jayfromsandiego. Try to post on Stackoverflow, or any of our myriad competitors. I certainly hope you will, if only so that you will find after the time it takes for you to register on each community and (re)post your "question" then wait for a response that may or may not ever come, only to find your question closed or ignored, or with a similar response to those you got here. This forum has a longstanding tradition of acceptance and hand holding that goes way beyond vast majority of programming forums that exist. As your question boils down to: "Here's what I want, code it for me?" don't be surprised when you get responses like ginerjm in even more blunt fashion. Meanwhile, NotSunfighter decided to take you up on your challenge and coded you up a solution. And just to be clear, noone (perhaps with the exception of NotSunfighter, after having spent valuable time trying to help you) cares whether you quit this forum. We are all volunteers. ginerjm may have been blunt, but he's right. We can all code. The vast majority of the people who answer questions like yours are professional developers. We are here to teach and share, and sometimes to simply tell someone the truth. The best I can hope for you at this moment is that you take a good hard look in the mirror at your own attitudes and approaches, and as the old saying goes "Don't cut off your nose to spite your face."
  17. Well here is where the variable is assigned: $human = $_POST['human']; This code will have issues if it's submitted without the various form fields filled in. You don't check for that for any of the form variables. Probably, the code would be better if all the form assignments was moved inside the the if ($_POST['submit'] ... condition because it makes no sense to try and process the form and assign local variables to form variables, if it wasn't. And in fact all the form variable assignments will benefit from changing them to be trimmed. $human = trim($_POST['human']); Better yet, if you want to leave the variable assignments at the top of the script, check that the variable actually exists so you don't get a runtime error if it doesn't: $human = !empty($_POST['human']) ? trim($_POST['human']) : ''; Now you fix your condition: if ($_POST['submit'] && strtolower($human) == 'wednesday') { Note that I fixed the quotes around wednesday. Originally they were backtics, which have a special function in PHP. Read these pages: trim, strtolower
  18. This is apples to oranges. 1. SSH to a shell on your host 2. Connect to localhost mysql server on port 3306 from shell on host Trying with Workbench: 1. Try to connect to localhost mysql on 3306 from your workstation See the problem? You could set up a port forward on your workstation, but Workbench and SQL pro both have some built in support for configuring forwarding in the client. See this article among many others out there if you google: https://www.digitalocean.com/community/tutorials/how-to-connect-to-a-mysql-server-remotely-with-mysql-workbench
  19. If you mean HTML I am doubtful anything near pure html with css and js will work. You could play with the Source view, but any forum is going to be extremely limited in what it allows you to put in. I don't know how much trouble you want to go to, but sites like Codepen, jsfiddle, jsbin etc. were built for that, so maybe that's a solution?
  20. In simplest form, PHP implements symbol table(s) which store variable names used in the script and zval(s) which are the actual data structures that manage variables. You could have 3 variable names: $a = $b = $c = 5; And this will have 3 symbol table entries but only 1 zval will be created. The zval has a reference count, so not surprisingly, this zval will have the value 3, indicating that there are 3 symbols using this zval. Now you change the value of one of the variables: $a++; As requinix states, PHP will make a new zval and copy the original value from the first zval. The symbol table entry for $a gets changed to point to the new zval, and the original zval has its reference count decremented by 1. $b and $c still point to the original zval. If you want to really geek out on PHP internals, there's an excellent series on PHP 7 vs 5 changes. The author also wrote a great article on the hashtable implementation that powers a lot of things in PHP including arrays. https://nikic.github.io/2015/05/05/Internal-value-representation-in-PHP-7-part-1.html https://nikic.github.io/2015/06/19/Internal-value-representation-in-PHP-7-part-2.html https://nikic.github.io/2014/12/22/PHPs-new-hashtable-implementation.html
  21. With most of these examples you are omitting blocks. Here is a block: { //Something } Many languages use the {} to denote a block. There are others that use something different, or use indentation (most notably python), but PHP is not one of those languages. Let's go back to an example you gave (Indentation mine): if($_POST['form']['hobby'] != '') echo "<br />"; $modUserEmailText .= '{hobby:caption} : {hobby:value}'; After your condition ($_POST['form']['hobby'] != '') You do not have a start block. So only the next line will be executed if the condition is true. I don't think that is what you expect. So you need a block around ALL the code that will execute if the condition is true: if($_POST['form']['hobby'] != '') { echo "<br />"; $modUserEmailText .= '{hobby:caption} : {hobby:value}'; } Obviously you are not giving us real code or are giving us snippets of the code as the errors don't correlate to the code you've provided, but perhaps this explanation will help you out. Just for completeness: if (!empty($_POST['form']['hobby']) { echo "<br />"; $modUserEmailText .= '{hobby:caption} : {hobby:value}' } This would be the proper way to handle the condition you are checking for. The problem with the code you presented, is that it will provide a runtime error if the $_POST['form']['hobby'] element does not exist. For things like checkboxes, this is a common occurrence. empty checks that the variable exists (isset) AND that it has a value (!= '''); You might also want to trim the value, as even a space would pass through your check and empty.
  22. Porbably the best solution in this case is to use media queries Here's an example that might help that targets phone sizes: /* Smartphones (portrait and landscape) ----------- */ @media only screen and (min-width: 320px) and (max-width: 480px) { .logo img { width: 60px; } /* other css rules */ } You can make alterations to the rules that drive the carousel using this technique, perhaps hiding it or doing something else.
  23. Top is something that you have to run for a while and watch while the server is under a sort of typical period of load. At any one instance it can be misleading, but if we take this at face value, it's telling you that your cpu's are doing almost nothing, so you have a lot of cpu power you could harness for additional work. Since you mention this server also runs a mysql db, I can assume that when you pull crypto data from the api's you mentioned you then process that data and store it in your mysql db. I can suggest to you that, with all the memory you have, and again assuming your db will grow over time, 2 things to look at: Make sure all your tables are InnoDB! If you did not declare them as such originally you can still use ALTER TABLE to change this. Take a large chunk of your available server memory (anywhere from 40-80%) and allocate it to the mysql innodb buffer pool. This is mysql InnoDB data cache which will cache the results of queries in mysql memory. Again you have to be somewhat careful that you retain enough memory for whatever else you might be doing. Here's one article with some algorithms for how to determine what to allocate and configure for your mysql server: https://scalegrid.io/blog/calculating-innodb-buffer-pool-size-for-your-mysql-server/ If you were to run for example, an AWS hosted MySQL server via their RDS service, you'd find that by default it's going to have allocated 80% of available instance memory to the buffer pool, so that gives you a good idea of what works well for most servers. Once you were to reconfigure mysql to allocate a big chunk of memory, you'll see the cache go way down accordingly, and the performance of mysql should improve again assuming your system does frequent queries of your crypto pricing data in MySQL.
  24. Echoing Requinix on this, but they aren't all that much different than an include/require of some code in a class body. Obviously better than that, from a documentation point of view, in that at least you see the declaration of the trait at the top of the class, but otherwise, it's about the same. In regards to interfaces, I would say it's best practice and certainly used in large projects and frameworks that class designers start with one or more interfaces to lay out the api contract. For example, take a look at the Laravel Cache system. Let's say you have a type of cache that doesn't come out of the box. How do you make your ACME cache work with Laravel? Laravel has a contracts directory where the interfaces are defined, and for cache we find this interface for a "Store" https://github.com/laravel/framework/blob/5.3/src/Illuminate/Contracts/Cache/Store.php You can see that this interface describes the cache api with methods like get, put, increment, decrement, forget, etc. When you look at the implementation of a specific cache store with bundled support like Redis for example, this is what you find in RedisStore: <?php namespace Illuminate\Cache; use Illuminate\Contracts\Cache\Store; use Illuminate\Contracts\Redis\Database as Redis; class RedisStore extends TaggableStore implements Store { /** * The Redis database connection. * * @var \Illuminate\Redis\Database */ protected $redis; /** * A string that should be prepended to keys. * * @var string */ protected $prefix; /** * The Redis connection that should be used. * * @var string */ protected $connection; /** * Create a new Redis store. * * @param \Illuminate\Redis\Database $redis * @param string $prefix * @param string $connection * @return void */ public function __construct(Redis $redis, $prefix = '', $connection = 'default') { $this->redis = $redis; $this->setPrefix($prefix); $this->setConnection($connection); } /** * Retrieve an item from the cache by key. * * @param string|array $key * @return mixed */ public function get($key) { if (! is_null($value = $this->connection()->get($this->prefix.$key))) { return $this->unserialize($value); } } /** * Store an item in the cache for a given number of minutes. * * @param string $key * @param mixed $value * @param float|int $minutes * @return void */ public function put($key, $value, $minutes) { $value = $this->serialize($value); $this->connection()->setex($this->prefix.$key, (int) max(1, $minutes * 60), $value); } So it should be fairly obvious to someone looking to add this capability to their Laravel project that an Acme cache will need an AcmeStore class that implements Illuminate\Contracts\Cache\Store. I looked around a bit at the Laravel Docs and found this section that outlines the same thing I've discussed using MongoDB as an example: https://laravel.com/docs/5.1/cache#adding-custom-cache-drivers As a dependency injection framework, there's going to be some sort of service system that takes care of instantiating a service, which is why this discusses how to register the store. Here is a MongoDB Laravel cache implementation I found on Packagist: https://github.com/alfa6661/laravel-mongodb-cache/blob/master/src/MongoStore.php When you look at this code, you'll see that it extends the Laravel DatabaseStore class rather than implementing the store interface, but that simply has to do with the fact that Mongo is a type of database and has some database-esque features that most pure cache servers don't have. When you look at the DatabaseStore Class you can see that it too implements the Store interface: class DatabaseStore implements Store { I think looking at how Laravel and Symfony have done things could be helpful in seeing the language features and techniques class designers use to create reusable and extendable class hierarchies. Another interesting example I could suggest to look at would be the Symfony finder component. It's a component library that facilitates searching for and working with files and directories on a local or network file system. The finder class implements 2 Standard PHP Library interfaces: class Finder implements \IteratorAggregate, \Countable This allows a finder object to be used in a statement like: if (count($finder) > 0). Implementing the IteratorAggregate interface facilitates iterating through an object using foreach(). If you are interested look at the implementation public function getIterator() in the class source. This is all far more interesting and important than Traits. You'll also probably start to notice that the interfaces are used to typehint dependency injected objects in related classes, which keeps those classes loosely coupled and yet still with some type resiliency. I can pass an object of a class that implements the interface, but if an object that does not implement the interface is passed, a fatal error will be generated.
  25. This is what Linux does. When the OS has lots of extra memory available it will use it to cache the filesystem. If more memory is needed it will take memory from cache and allocate it. You can think of it as Linux being proactive in making use of an available resource rather than having it go to waste. In regards to your site, the main question would be what level of CPU usage (top is a good tool to start with) you have, and what else the server is being utilized for. I don't know if you can increase the number of processes that are pulling crypto price data, or processes that are doing other sorts of data or number crunching to make more use of the memory and cpu resources you have. If this server also hosts a website that handles clients and displays data or allows for searching, it might be better to just be satisfied that you have ample headroom, and work on building up your audience. Really nobody could advise you without knowing more about what you are doing, but there is no reason to worry about your cache, until such time as your server becomes IO bound, and you are seeing sluggishness and lots of IOWait, where the machine is doing nothing as it waits on the reading & writing of data.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.