I have a form that users fill out, and on the form there are multiple identical fields, like «project name», «project date», «catagory», etc. Based on how many forms a user is submitting, my goal is to:
- loop over the number of forms
- create individual SQL insert statements
However, PHP throws me a NOTICE that I don’t seem to understand:
Notice:
Notice: Uninitialized string offset: 1 …dataPasser.php on line 90
PHP
$myQuery = array();
if ($varsCount != 0)
{
for ($i=0; $i <= $varsCount; $i++)
{
$var = "insert into projectData values ('" . $catagory[$i] . "', '" . $task[$i] . "', '" . $fullText[$i] . "', '" . $dueDate[$i] . "', null, '" . $empId[$i] ."')";
array_push($myQuery, $var);
}
}
There are references to this issue I am having, but they are not exact and I am having trouble deducing where the actual problem stems from. I would greatly appreciate any help in understanding what is causing the array to not initialize properly.
Есть функция шифровки/расшифровки строки по ключу, при расшифровке пишет предупреждения:
Notice: Uninitialized string offset: 63 in [...][...] on line 18
Notice: Uninitialized string offset: 63 in [...][...] on line 19
Это строки:
$tmp = md5(md5($key.$strofsym[$x-1]).$key);
$encoded = str_replace($tmp[3].$tmp[6].$tmp[1].$tmp[2], $strofsym[$x-1], $encoded);
Сами функции:
function encode($unencoded,$key){ //Шифрование
$string=base64_encode($unencoded);
$newstr = '';
$arr=array();
$x=0;
while ($x++< strlen($string)) {
$arr[$x-1] = md5(md5($key.$string[$x-1]).$key);
$newstr = $newstr.$arr[$x-1][3].$arr[$x-1][6].$arr[$x-1][1].$arr[$x-1][2];
}
return $newstr;
}
function decode($encoded, $key){ //Расшифровка
$strofsym='qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM=';
$x=0;
while ($x++<= strlen($strofsym)) {
$tmp = md5(md5($key.$strofsym[$x-1]).$key);
$encoded = str_replace($tmp[3].$tmp[6].$tmp[1].$tmp[2], $strofsym[$x-1], $encoded);
}
return base64_decode($encoded);
}
echo decode('70072bbbd45b597a700751f437683768','z');
Не критично, но бесит
Vagrant 0 / 0 / 0 Регистрация: 11.01.2016 Сообщений: 5 |
||||||||
1 |
||||||||
12.01.2016, 13:17. Показов 4577. Ответов 7 Метки нет (Все метки)
Доброго времени суток всем. Кратко суть: при парсинге страницы с помощью simple_html_dom.php сталкиваюсь с предупреждением типа Код Notice: Uninitialized string offset: 0 in C:%путь%simple_html_dom.php on line 707 вот код, который использую я:
при этом вышеуказанный notice появляется ровно столько раз, сколько в коде конструкций типа
После часов поисков в интернете и на форуме, пришел к выводу что наилучший способ решения проблемы в моем конкретном случае — на время работы «моего» парсера отключить ошибки типа E_NOTICE, а потом вернуть все как было. Заранее благодарю за помощь.
0 |
xpoince 182 / 182 / 83 Регистрация: 18.02.2014 Сообщений: 867 |
||||
12.01.2016, 14:39 |
2 |
|||
Vagrant, просто переменная пустая. Кидаете пустышку вот он и пугается. надо сделать проверку на
0 |
Vagrant 0 / 0 / 0 Регистрация: 11.01.2016 Сообщений: 5 |
||||
12.01.2016, 15:41 [ТС] |
3 |
|||
xpoince, какая именно переменная у меня пустая?.
таки выводит нужные мне ссылки.
0 |
xpoince 182 / 182 / 83 Регистрация: 18.02.2014 Сообщений: 867 |
||||
12.01.2016, 15:49 |
4 |
|||
Vagrant, Вот наглядный пример.
0 |
0 / 0 / 0 Регистрация: 11.01.2016 Сообщений: 5 |
|
12.01.2016, 18:24 [ТС] |
5 |
xpoince, повторюсь, я начал разбирать азы php совсем недавно, поэтому я (надеюсь, временно) не сильно разбираюсь во всех тонкостях. Но, исходя из вашего примера, у меня в каком-то из массивов (предполагаю, массив ссылок) есть элемент типа string с пустым содержанием, так? и если так, то обрабатывается он кодом библиотеки simple_html_dom.php, что опять таки приводит меня к варианту временного отключения обработки E_NOTICE. Добавлено через 1 час 55 минут Спасибо огромное, узнал для себя что-то новое
0 |
182 / 182 / 83 Регистрация: 18.02.2014 Сообщений: 867 |
|
12.01.2016, 18:47 |
6 |
Vagrant, к сожалению это не проще. Почитайте что вы скрыли. @ лучше избегать в использование, бывают случаи когда надо @ использовать, но это не есть хорошо. Вы в таком случае могли просто убрать notice и все. @ не покажет вам критическую ошибку и вы будете тратить кучу времени что бы вспомнить где вы прописали @ да и вообще если вспомните что писали @
0 |
25 / 25 / 15 Регистрация: 12.10.2013 Сообщений: 183 |
|
12.01.2016, 18:54 |
7 |
да и вообще если вспомните что писали @ Правильно ли понимаю, что @ — сокрытие критической ошибки в месте установки @?
0 |
0 / 0 / 0 Регистрация: 11.01.2016 Сообщений: 5 |
|
12.01.2016, 19:28 [ТС] |
8 |
xpoince, я изначально и формулировал суть задачи:
сохранить текущее состояние->от ключить уровень E_NOTICE->собственно парсинг->вернуть изначальное состояние а «@» делает какраз то что нужно. n0n4m3r, да, «@» заставляет php игнорировать любые ошибки в выражениях. Выражение, как я понял, является единственно-правильным местом его использования.
0 |
* xdebug isn't built into the nightly PHP, so we'll get an error if we try to remove it; nightly should also be allow failures untilany identified issues are resolved * <>/!= * Update to versions of complex and matrix libraries * Set formula attribute in the Xlsx reader * Calculation/DateTime Failure With PHP8 (#1661) The following code generates an error with PHP8: if ($t1[1] > 29) { $t1[1] += 1900; Under the "right" conditions, PHP8 evaluates the condition as true when PHP8 is a non-numeric string and then generates an error trying to perform += on that non-numeric string. Adding a numeric test eliminates the problem. All unit tests involving this code now succeed with both PHP7 and PHP8. * Update to versions of complex and matrix libraries * Reader/Gnumeric Failure with PHP8 (#1662) * Reader/Gnumeric Failure with PHP8 An explicit cast from SimpleXML to int is now needed with PHP8, where it was performed implicitly with PHP7. Unit tests run correctly for both PHP7 and PHP8 on corrected code. * ReverseSort bug, exposed but not caused by PHP8 (#1660) Some tests of ReferenceHelper functions columnReverseSort and cellReverseSort which passed with PHP7 fail with PHP8. Both functions use the following construction: return 1 - strcasecmp(whatever); The "1" seems very mysterious. I believe that the correct code should be: return -strcasecmp(whatever); It appears in particular that PHP7 strcasecmp was never returning a value of 1 for the tests in question, but PHP8 strcasecmp does so. With the corrected code, the tests pass in both PHP7 and PHP8. * Drop $this->spreadSheet null check from Xlsx Writer (#1646) $this->spreadSheet cannot be null * Update index.md (#1620) * Bug setting Superscript/Subscript to false (#1567) If font style Superscript is set to true, Subscript is set to false. Likewise, setting Subscript to true sets Superscript to false. Both of these are working as they should. However, setting Superscript to false causes Subscript to be set to true, and setting Subscript to false causes Superscript to be set to true. I believe that is an error in both cases. This change fixes it. There seem to be no existing tests for Font styles. I added the tests necessary to validate this change. I will put adding more on my to-do list. * Update CHANGELOG * Sync README * Separate compoer.json for PHP8 to enforce phpunit ^9.3 * We don't want the composer lock file for PHP8 * Work with existing composer file; but force a fresh install to require new dependency versions * Allow failures on nightly * Allow failures on nightly fails if we remove it from the grid * fixed php8 deprecation warning for libxml_disable_entity_loader() (#1625) * fixed php8 deprecation warning for libxml_disable_entity_loader() * Use ZipArchive methods as zip_* functions are deprecated in PHP8 * Remove tests that include tcPDF and DomPDF libraries when running against PHP8, because neither library is yet PHP8-ready * Let's try to figure out why we're having an issue with a temp csv file * Need to add `application/csv` to the list of valid CSV mime types * Locale-specific float to string is changed in PHP as per https://wiki.php.net/rfc/locale_independent_float_to_string * Codestyle clean-ups * Switch from using poser badges to shields.io because poser wasn't picking up the correct license * Update composer suggestions * Introduce GitHub Actions The plan is to keep Travis for a short while, until we are confident that GitHub Actions work well enough for us. And after that we can remove Travis entirely. There is a bunch of duplicated things but it allows us to maximize parallelismt to have results as soon as possible. API documentation generation is still missing. * Annotate problems in code * Publish API docs via GitHub Actions * Update composer suggestions * Test PHP 8 on GitHub Actions * Improving Coverage for Excel2003 XML Reader (#1557) * Improving Coverage for Excel2003 XML Reader Reader/Xml is now 100% covered. File templates/Excel2003XMLTest.xml, used in some tests, is *not* readable by a current version of Excel. I have substituted a new file excel2003.xml to be used in its place. I have not deleted the original in case someone in future (possibly me) wants to see what it needs to make it usable. There are minimal code changes. - Unused protected functions pixel2WidthUnits and widthUnits2Pixel are deleted. - One regex looking to convert hex characters is changed from a-z to a-f, and made case insensitive. - No calculation performed for "error" cell (previously calculation was attempted and threw exception). - Empty relative row/cell is now handled correctly. - Style applied to empty cell when appropriate. - Support added for textRotation. - Support added for border styles. - Support added for diagonal borders. - Support added for superscript and subscript. - Support added for fill patterns. In theory, encodings other than UTF-8 were supported. In fact, I was unable to get SecurityScanner to pass *any* xml which is not UTF-8. Eliminating the assumption that strings might not be UTF-8 allowed much of the code to be greatly simplified. After that, I added some code that would permit the use of some ASCII-compatible encodings (there is a test of ISO-8859-1). It would be more difficult to handle other encodings (such as UTF-16). I am not convinced that even the ISO-8859 effort is worth it, but am willing to investigate either expanding or eliminating non-UTF8 support. I added a number of tests, creating an Xml directory, and moving XmlTest to that directory. Pull Request had problems reading old invalid sample in the code coverage phase, not in any of the other test phases, and not in the code coverage phase on my local machine. As it turns out, aside from being invalid, the sample is much larger than any of the other samples. Tests have been adjusted accordingly. * Smaller Test File Should eliminate need to avoid test during xml coverage. * Break Up Style Test into Multiple Tests Per suggestion from Mark Baker. * Integrate AddressHelper Change The introduction of AddressHelper introduced a conflict which needed to be resolved. I wanted to test it locally before resolving. This required me to add (unchanged) AddressHelper to my local copy. I hope this is an okay manner of resolving the conflict. * Weird Travis Error XmlOddTest works just fine on my local machine, but Travis failed it. Even worse, the lines which Travis flags don't even make any sense (one was the empty line between two methods!). This test is not essential to the rest of the change. I am removing it from the package, and will attempt to re-add it when I have a chance to sync up my fork with the main project. * Update CHANGELOG * 1.15.0 * Remove coverage from Travis Coverage data were not correctly uploaded for a long time now, and it now is uploaded via GitHub Actions * Prepare for next version * Ensure that the list of shared formulae is maintained while chunk-reading Xlsx Files (#1680) * Ensure that the list of shared formulae is maintained while chunk-reading Xlsx files * Prevent notice during accessing "cached magnification factor" offset Sheet View Settings Block should be 8-14 bytes long in BIFF8 Excel 97 according to the open office file format documentation. However access to byte 10 and 12 is not possible when record data is malformed, so getUInt2d throws notice. * Refresh lock files * Add exportArray Method for Styles (#1580) Issue #580 has gone stale since I started work on this. Nevertheless, this implements an exportArray function as an exact counterpart of applyFromArry. I chose the name exportArray to avoid confusion with the existing method getStyleArray, which does something completely different. This change also increases coverage for all the Style classes to 100%, with the exception of Style.php itself. There were several (unchanged) places in Style.php where I did not have sufficient understanding of what was supposed to be happening, so could not create tests. All properties used by applyFromArray are exported by this method. Note that conditional styles are not covered; this is consistent with the fact that they are not covered by applyFromArray. The method is implemented as a final public function in Style/Supervisor, which calls abstract protected function exportArray1, which is implemented in each of the subclasses, and which calls final protected function exportArray2 in Style/Supervisor. So exportArray is usable for any of the subclasses as well. The new method is added to the documentation. The existing documentation for applyFromArray was alphabetized to make it easier to follow. One property (Style quotePrefix) was added to the documentation. Some Borders pseudo-properties (vertical, horizontal, and outline) were documented as usable by applyFromArray, but aren't actually supported - they were removed. The documentation of the properties seemed to use setProperty and getProperty fairly randomly - it now uses setProperty exclusively. New constants were added for the textRotation "angles" used to create a "stacked" cell. I felt that changing the readers and writers to use these constants was beyond the scope of this change, but it is on my to-do list. * Updating a misspelling of a function name. (#1695) This will update the function name DCOUNTA from the misspelling of DCOUNT. * Make DefinedNames Samples Consistent With Other Samples (#1707) All other Samples write to temporary directory. DefinedNames samples write to main directory, which (a) means they aren't stored with others, and (b) they aren't ignored by git so look like changed files. The tests are also simplified by requiring Header rather than Bootstrap, making use of Helper. * Resolve XSS Vulnerability in the HTML Writer (#1719) Resolve XSS Vulnerability in the HTML Writer * Drop Travis * Automatic GitHub releases from git tags * Improve Coverage in src/PhpSpreadsheet There are no changes to code. Additional tests are added, so that the following 6 items now have 100% test coverage: - Comment - DefinedName - DocumentGenerator - IOFactory - NamedFormula - NamedRange * Changes for Scrutinizer Two changes to fix minor problems reported by Scrutinizer. * Spelling: Tou -> You * Fix for 1735 (Incorrect activeSheetIndex after RemoveSheetByIndex) (#1743) This is a fix for issue #1735. It adds tests for this situation, and similar situations involving adding new sheets and accessing existing ones. Coverage for Spreadsheet.php increases from 69% to 75% as a result. * Update change log * Fix for 3 Issues Involving ReadXlsx and NamedRange (#1742) * Fix for 3 Issues Involving ReadXlsx and NamedRange Issues #1686 and #1723, which provide sample spreadsheets, are probably solved by this ticket. Issue #1730 is also probably solved, but I have no way to verify. There are two problems with how PhpSpreadsheet is handling things now. Although the first problem is much less severe, and isn't really a factor in the issues named above, it is helpful to get it out of the way first. If you define a named range in Excel, and then delete the sheet where the range exists, Excel saves the range as #REF!. If there is a cell which references the range, it will similarly have the value #REF! when you open the Excel file. Currently, PhpSpreadsheet discards the #REF! definition, so a cell which references the range will appear as #NAME? rather than #REF!. This PR changes the behavior so that PhpSpreadsheet retains the #REF! definition, and cells which reference it will appear as #REF!. The second problem is the more severe, and is, I believe, responsible for the 3 issues identified above. If you define a named range and the sheet on which the range is defined does not exist at the time, Excel will save the range as something like: '[1]Unknown Sheet'!$A$1 If a cell references such a range, Excel will again display #REF!. PhpSpreadsheet currently throws an Exception when it encounters such a definition while reading the file. This PR changes the behavior so that PhpSpreadsheet saves the definition as #REF!, and cells which reference it will behave similarly. For the record, I will note that Excel does not magically recalculate when a missing sheet is subsequently added, despite the fact that the reference might now become resolvable. PhpSpreadsheet behaves likewise. * Remove Dead Code in Test Identified it after push but before merge. * Update change log * Apply Column and Row Styles to Existing Cells (#1721) * Apply Column and Row Styles to Existing Cells This is a fix for issue #1712. When a style is applied to an entire row or column, it is currently only effective for cells which don't already contain a value. The code needs to iterate through existing cells in the row/column in order to apply the style to them. This could be considered a breaking change, however, I believe that the change makes things operate as users would expect, and that the existing implementation is incomplete. The change also removes protected element conditionalStyles from the Style class. That element is an unused remnant, and can no longer be set or retrieved - methods getConditionalStyles and setConditionalStyles actually act on an element in the Worksheet class. Finally, additional tests are added so that Style, and in fact the entire Style directory, now has 100% test coverage. * Scrutinizer Changes Scrutinizer flagged 6 statements. 5 can be easily corrected. One is absolutely wrong (it thinks iterating through cells in column can return null). Let's see if we can satisfy it. * Remove Exception For CellIterator on Empty Row/Column For my first attempt at this change, which corrects a bug by updating styles for non-empty cells when a style is set on a row or column, I wished to make things more efficient by using setIterateOnlyExistingCells, something which the existing documentation recommends. This caused an exception to be generated when the row or column is empty. So I removed that part of the change while I researched what was going on. I have completed that research. The existing code does throw an exception when the row/column is empty and iterateOnlyExistingCells is true. However, that does not seem like a reasonable action. This situation is analagous to iterating over an empty array, and that action is legal and does not throw. The same should apply here. There were no tests for this situation, and now there are. I have added additional tests, and coverage for all of RowCellIterator, ColumnCellIterator, and CellIterator are all now 100%. Some of my new tests were added in new members, because the existing tests all relied on mocking, which was not the best choice for the new tests. One of the existing tests for RowCellIteratorTest (testSeekOutOfRange) was wrong; it issued the expected exception, but for the wrong reason. I have added an additional test to ensure that it fails "correctly". The existing documentation says that the default value for IterateOnlyExistingCells is true. In fact, the default value is false. I have corrected the documentation. * More Scrutinizer I believe its analysis is incorrect, but this should silence it. * DocBlock Correction ColumnCellIterator DocBlock for current indicated it could return null or Cell, but it can really return only Cell. This had caused Scrutinizer to complain earlier. * PHP8 Environment Appears to be Fixed Cosmetic change to Doc member. I suspect there is a way to rerun all the tests without another push, but I have been unable to figure out how. * Update change log * TextData Coverage and Minor Bug Fixes (#1744) This had been intended to get 100% coverage for TextData functions, and it does that. However, some minor bugs requiring source changes arose during testing. - the Excel CHAR function restricts its argument to 1-255. PhpSpreadsheet CHARACTER had been allowing 0+. Also, there is no need to test if iconv exists, since it is part of Composer requirements. - The DOLLAR function had been returning NUM for invalid arguments. Excel returns VALUE. Also, negative amounts were not being handled correctly. - The FIXEDFORMAT function had been returning NUM for invalid arguments. Excel FIXED returns VALUE. * Replace anti-xss with html purifier (#1751) * Replace voku/anti-xss with ezyang/htmlpurifier. Despite anti-xss being a smaller footprint dependency, an a better license fit with our MIT license, there are issues with it's automatic it sanitisation of global variables causing side effects * Additional unit tests for xss in html writer cell comments * Fix bug #1626 where values of 0 were "rounded" up/down as if they were not 0 (#1627) * Fix bug where values of 0 were "rounded" up/down as if they were not 0 * Update change log * Fix for #1612 - SLK Long File Name (#1706) Issue has been marked stale, but ... Sylk read sets worksheet title to filename (minus .slk). If that is >31 characters, PhpSpreadsheet throws Exception. This change truncates sheet title, as Excel does, to 31 characters. * Update change log * worksheet: fix if cellValue does not exist (#1727) The condition is FALSE if the cell does not exist in the flipped table, but anyway, it is sent in to a method requiring 'string' type, causing it to fail. * fixes #1655 issue (#1656) Resolve problem with incorrectly defined hyperlinks * Add 'ps' suffix to printer settings resources IDs (#1690) * Add 'ps' suffix to printer settings resources IDs * Update change log * Fix pixelsToPoints conversion (for HTML col width) (#1733) * DocBlock Change in Styles/Conditional (#1697) Scrutinizer reported a minor error in a test involving a module which I was not changing. Styles/Conditional function setConditions can take a scalar or an array as a parameter, but DocBlock says it only expects array. I did not wish to add the extra module to my PR, but made a note to self to fix that after PR was installed. That has now happened, and it makes for a good case for me to see all the PHP8/Composer2/etc. changes that have happened recently. * Merge pull request #1698 * Merge pull request #4 from PHPOffice/master * Restore Omitted Read XML Test * Fix for bug #1592 (UPDATED) (#1623) * Fix for Xls when BIFF8 SST (FCh) has bad Shared string length * Update change log * Add nightly PHP 8.1 dev to github actions (#1763) * Fix compatibility with ext-gd on php 8 (#1762) * CSV - Guess Encoding, Handle Null-string Escape (#1717) * CSV - Guess Encoding, Handle Null-string Escape This is in response to issue #1647 (detect CSV character encoding). First, my tests with mb_detect_encoding indicate that it doesn't work well enough; regardless, users can always do that on their own if they deem it useful. Rolling my own is also troublesome, but I can at least: a. Check for BOM (UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE). b. Do some heuristic tests for each of the above encodings. c. Fallback to a user-specified encoding (default CP1252) if a and b don't yield result. I think this is probably useful enough to include, and relatively easy to expand if other potential encodings should be considered. Starting with PHP7.4, fgetcsv allows specification of null string as escape character in fgetcsv. This is a much better choice than the PHP (and PhpSpreadsheet) default of backslash in that it handles the file in the same manner as Excel does. There is one statement in Reader/CSV which would be adversely affected if the caller so specified (building a regular expression under the assumption that escape character is a single character). Fix that statement appropriately and add tests. * Update changelog * Update Units of Measure supported by the CONVERT() function (#1768) Now supports all current UoM in all categories, with both 1- and 2-character multiplier prefixes, and binary multiplier prefixes, including the new Temperature scales * Changelog for 1.16.0 release * Fix date tests withut specified year for current year 2021 (#1774) * Mrand of zero to any multiple should return 0 (#1773) * Problems Using Builtin PHP Functions Directly As Excel Functions (#1799) * Problems Using Builtin PHP Functions Directly As Excel Functions This fixes issue #1789. As originally reported, stricter typing was causing PHP8 to throw an exception when a non-numeric value was passed to the Round function. Previous releases of PHP did not see this problem, however, on further analysis, they were also incorrect in returning 0 as the result in the erroneous situation, when they should have been returning a VALUE error. Yet more analysis showed that other functions would also have problems, and, in addition, might not handle invalid input (e.g. a negative length passed to REPT) or output (e.g. NAN in the case of ACOS(2)) correctly. The following MathTrig functions are affected: ABS, ACOS, ACOSH, ASIN, ASINH, ATAN, ATANH, COS, COSH, DEGREES (rad2deg), EXP, LN (log), LOG10, RADIANS (deg2rad), REPT (str_repeat), SIN, SINH, SQRT, TAN, TANH. One TextData function (REPT) is also affected. This change lets PhpSpreadsheet validate the input for each of these functions before passing control to the builtin, and handle the output afterwards. There were no explicit tests for any of these functions, a fact made easy to ignore by the fact that PhpSpreadsheet delegated the heavy lifting to PHP itself for these cases. A full suite of tests is now added for each of the affected functions. * Scrutinizer Recommendations Only in 3 modules which are part of this PR. * Improved Handling of Tan(PI/2) Return DIV0 error for TAN when COS is very small. * Additional Trig Tests Results which should be infinity, i.e. DIV/0 error. * Delete Temporary Files In XssVulnerabilityTest (#1800) * Delete Temporary Files In XssVulnerabilityTest They need not exist after the test. Some of them are placed in current directory, which means Git thinks they are needed. * Update Changelog for switch from built-in PHP functions to Excel class methods (to handle typechecking for stricter PHP8 typing) * Fix For #1772 Null Exception on ODS Read (#1776) Fix for #1772. Header and Footer Properties may be omitted in Page Setting Style Set. Code changed to allow for this possibility, and tests added. * Additional method call/return typing * Update Changelog * PHPCS Resolutions * Fix Xlsx reader overriding manually set number format with builtin number format (#1805) * Update Changelog * Named formula fix for empty formula value * Do not swallow previous exception (#1778) The previous exception will be included when loading the content as DOM Document fails. This makes debugging the reason behind the failure much easier. * Support DataBar of conditional formatting rule (#1754) Implemented the databar of Conditional Type for XLSX Files. - DataBar can be read, written, and added for basic use. - Supports reading, writing and adding using "extLst". About "extLst" - https://docs.microsoft.com/en-us/openspecs/office_standards/ms-xlsx/07d607af-5618-4ca2-b683-6a78dc0d9627 The following setting items on the Excel setting screen can be read, written, and added. - (minimum, maximum)type: Automatic, LowestValue, Number, Percent, Formula, Percentile - Direction: context, leftToRight, rightToLeft (show data bar only) - Fills Solid, Gradient - FillColor: PositiveValues, NegativeValues - Borders: Solid, None - BorderColor: PositiveValues, NegativeValues - Axis position: Automatic, Midpoint, None - Axis color * formatAsDate strip language metadata (#1618) * Revert "Fix cant get right format chinese date format error" This reverts commit 8c58385d6c103d23f6a5b3d1899a5e7cc8f66e92. * formatAsDate strip language metadata (fixes #1616) Co-authored-by: Mark Baker <mark@lange.demon.co.uk> * Additional method call/return typing * Composer fixes * PHPCS Fixes * Additional unit tests for statistical functions, with a fix to ordering for RANK() (#1813) * Additional unit tests for statistical functions, with a fix to ordering for RANK() * Unhappy path unit tests (#1814) * Unhappy path unit tests * Fix unhappy error for BETADIST and BETAINV min/max range * Additional unit tests for previously untested financial functions (#1815) * Additional unit tests for previously untested financial functions, and some additions to follow untested paths * Start splitting Financial function tests out from the large FinancialTests class into individual test classes for each function * Extract remaining Excel function unit tests into separate test classes for each function (#1817) * Extract remaining Financial function unit tests into separate test classes for each function This makes it easier to manage unit tests if they are individual files rather than all in a single file It also provides a stepping stone toward making it easier to test Excel functions when Excel errors no longer return a string, but an actual Excel exception that can be handled more cleanly * Additional statistical unit tests (#1818) * Inherited Scrutinizer Recommendations - 1 of 3 (#1806) * Make DefinedNames Samples Consistent With Other Samples (#1707) All other Samples write to temporary directory. DefinedNames samples write to main directory, which (a) means they aren't stored with others, and (b) they aren't ignored by git so look like changed files. The tests are also simplified by requiring Header rather than Bootstrap, making use of Helper. * Resolve XSS Vulnerability in the HTML Writer (#1719) Resolve XSS Vulnerability in the HTML Writer * Drop Travis * Automatic GitHub releases from git tags * Improve Coverage in src/PhpSpreadsheet There are no changes to code. Additional tests are added, so that the following 6 items now have 100% test coverage: - Comment - DefinedName - DocumentGenerator - IOFactory - NamedFormula - NamedRange * Changes for Scrutinizer Two changes to fix minor problems reported by Scrutinizer. * Spelling: Tou -> You * Fix for 1735 (Incorrect activeSheetIndex after RemoveSheetByIndex) (#1743) This is a fix for issue #1735. It adds tests for this situation, and similar situations involving adding new sheets and accessing existing ones. Coverage for Spreadsheet.php increases from 69% to 75% as a result. * Update change log * Fix for 3 Issues Involving ReadXlsx and NamedRange (#1742) * Fix for 3 Issues Involving ReadXlsx and NamedRange Issues #1686 and #1723, which provide sample spreadsheets, are probably solved by this ticket. Issue #1730 is also probably solved, but I have no way to verify. There are two problems with how PhpSpreadsheet is handling things now. Although the first problem is much less severe, and isn't really a factor in the issues named above, it is helpful to get it out of the way first. If you define a named range in Excel, and then delete the sheet where the range exists, Excel saves the range as #REF!. If there is a cell which references the range, it will similarly have the value #REF! when you open the Excel file. Currently, PhpSpreadsheet discards the #REF! definition, so a cell which references the range will appear as #NAME? rather than #REF!. This PR changes the behavior so that PhpSpreadsheet retains the #REF! definition, and cells which reference it will appear as #REF!. The second problem is the more severe, and is, I believe, responsible for the 3 issues identified above. If you define a named range and the sheet on which the range is defined does not exist at the time, Excel will save the range as something like: '[1]Unknown Sheet'!$A$1 If a cell references such a range, Excel will again display #REF!. PhpSpreadsheet currently throws an Exception when it encounters such a definition while reading the file. This PR changes the behavior so that PhpSpreadsheet saves the definition as #REF!, and cells which reference it will behave similarly. For the record, I will note that Excel does not magically recalculate when a missing sheet is subsequently added, despite the fact that the reference might now become resolvable. PhpSpreadsheet behaves likewise. * Remove Dead Code in Test Identified it after push but before merge. * Update change log * Apply Column and Row Styles to Existing Cells (#1721) * Apply Column and Row Styles to Existing Cells This is a fix for issue #1712. When a style is applied to an entire row or column, it is currently only effective for cells which don't already contain a value. The code needs to iterate through existing cells in the row/column in order to apply the style to them. This could be considered a breaking change, however, I believe that the change makes things operate as users would expect, and that the existing implementation is incomplete. The change also removes protected element conditionalStyles from the Style class. That element is an unused remnant, and can no longer be set or retrieved - methods getConditionalStyles and setConditionalStyles actually act on an element in the Worksheet class. Finally, additional tests are added so that Style, and in fact the entire Style directory, now has 100% test coverage. * Scrutinizer Changes Scrutinizer flagged 6 statements. 5 can be easily corrected. One is absolutely wrong (it thinks iterating through cells in column can return null). Let's see if we can satisfy it. * Remove Exception For CellIterator on Empty Row/Column For my first attempt at this change, which corrects a bug by updating styles for non-empty cells when a style is set on a row or column, I wished to make things more efficient by using setIterateOnlyExistingCells, something which the existing documentation recommends. This caused an exception to be generated when the row or column is empty. So I removed that part of the change while I researched what was going on. I have completed that research. The existing code does throw an exception when the row/column is empty and iterateOnlyExistingCells is true. However, that does not seem like a reasonable action. This situation is analagous to iterating over an empty array, and that action is legal and does not throw. The same should apply here. There were no tests for this situation, and now there are. I have added additional tests, and coverage for all of RowCellIterator, ColumnCellIterator, and CellIterator are all now 100%. Some of my new tests were added in new members, because the existing tests all relied on mocking, which was not the best choice for the new tests. One of the existing tests for RowCellIteratorTest (testSeekOutOfRange) was wrong; it issued the expected exception, but for the wrong reason. I have added an additional test to ensure that it fails "correctly". The existing documentation says that the default value for IterateOnlyExistingCells is true. In fact, the default value is false. I have corrected the documentation. * More Scrutinizer I believe its analysis is incorrect, but this should silence it. * DocBlock Correction ColumnCellIterator DocBlock for current indicated it could return null or Cell, but it can really return only Cell. This had caused Scrutinizer to complain earlier. * PHP8 Environment Appears to be Fixed Cosmetic change to Doc member. I suspect there is a way to rerun all the tests without another push, but I have been unable to figure out how. * Update change log * TextData Coverage and Minor Bug Fixes (#1744) This had been intended to get 100% coverage for TextData functions, and it does that. However, some minor bugs requiring source changes arose during testing. - the Excel CHAR function restricts its argument to 1-255. PhpSpreadsheet CHARACTER had been allowing 0+. Also, there is no need to test if iconv exists, since it is part of Composer requirements. - The DOLLAR function had been returning NUM for invalid arguments. Excel returns VALUE. Also, negative amounts were not being handled correctly. - The FIXEDFORMAT function had been returning NUM for invalid arguments. Excel FIXED returns VALUE. * Replace anti-xss with html purifier (#1751) * Replace voku/anti-xss with ezyang/htmlpurifier. Despite anti-xss being a smaller footprint dependency, an a better license fit with our MIT license, there are issues with it's automatic it sanitisation of global variables causing side effects * Additional unit tests for xss in html writer cell comments * Fix bug #1626 where values of 0 were "rounded" up/down as if they were not 0 (#1627) * Fix bug where values of 0 were "rounded" up/down as if they were not 0 * Update change log * Fix for #1612 - SLK Long File Name (#1706) Issue has been marked stale, but ... Sylk read sets worksheet title to filename (minus .slk). If that is >31 characters, PhpSpreadsheet throws Exception. This change truncates sheet title, as Excel does, to 31 characters. * Update change log * worksheet: fix if cellValue does not exist (#1727) The condition is FALSE if the cell does not exist in the flipped table, but anyway, it is sent in to a method requiring 'string' type, causing it to fail. * fixes #1655 issue (#1656) Resolve problem with incorrectly defined hyperlinks * Add 'ps' suffix to printer settings resources IDs (#1690) * Add 'ps' suffix to printer settings resources IDs * Update change log * Fix pixelsToPoints conversion (for HTML col width) (#1733) * DocBlock Change in Styles/Conditional (#1697) Scrutinizer reported a minor error in a test involving a module which I was not changing. Styles/Conditional function setConditions can take a scalar or an array as a parameter, but DocBlock says it only expects array. I did not wish to add the extra module to my PR, but made a note to self to fix that after PR was installed. That has now happened, and it makes for a good case for me to see all the PHP8/Composer2/etc. changes that have happened recently. * Merge pull request #1698 * Merge pull request #4 from PHPOffice/master * Restore Omitted Read XML Test * Fix for bug #1592 (UPDATED) (#1623) * Fix for Xls when BIFF8 SST (FCh) has bad Shared string length * Update change log * Add nightly PHP 8.1 dev to github actions (#1763) * Fix compatibility with ext-gd on php 8 (#1762) * CSV - Guess Encoding, Handle Null-string Escape (#1717) * CSV - Guess Encoding, Handle Null-string Escape This is in response to issue #1647 (detect CSV character encoding). First, my tests with mb_detect_encoding indicate that it doesn't work well enough; regardless, users can always do that on their own if they deem it useful. Rolling my own is also troublesome, but I can at least: a. Check for BOM (UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE). b. Do some heuristic tests for each of the above encodings. c. Fallback to a user-specified encoding (default CP1252) if a and b don't yield result. I think this is probably useful enough to include, and relatively easy to expand if other potential encodings should be considered. Starting with PHP7.4, fgetcsv allows specification of null string as escape character in fgetcsv. This is a much better choice than the PHP (and PhpSpreadsheet) default of backslash in that it handles the file in the same manner as Excel does. There is one statement in Reader/CSV which would be adversely affected if the caller so specified (building a regular expression under the assumption that escape character is a single character). Fix that statement appropriately and add tests. * Update changelog * Update Units of Measure supported by the CONVERT() function (#1768) Now supports all current UoM in all categories, with both 1- and 2-character multiplier prefixes, and binary multiplier prefixes, including the new Temperature scales * Changelog for 1.16.0 release * Fix date tests withut specified year for current year 2021 (#1774) * Mrand of zero to any multiple should return 0 (#1773) * WIP Inherited Scrutinizer Recommendations - 1 of 3 I tried to sync my fork with the main project, as I have done several times before. However, the GitHub interface to do this had changed, and it appears that I did not make the optimal selection when I had a choice. Consequently, all the merges that happened to base between the last time I synchronized and this time appear to be part of any PR that I push. "Files changed" remains correct for my new PRs, but there appear to be many more commits involved than is actually the case. I will, at some point, delete and re-create my fork, and pay much closer attention in future when I want to sync my fork with the main project. Because of this set-up, Scrutinizer reports flaws in code that I haven't actually changed in my PRs #1799 and #1800. It still passes them, but, as long as I'm aware of the problems, I may as well attempt to correct them. The following are not part of those PRs: - 5 problems spread over 4 different members - 12 problems in Calculation/Engineering - 15 problems in Reader/XML I shall attempt to resolve these via 3 separate PRs, of which this is the first. * Try Hyperlink Again Scrutinizer still didn't like it as fixed. * Another Crack at Hyperlink This should work. Co-authored-by: Mark Baker <mark@lange.demon.co.uk> Co-authored-by: Adrien Crivelli <adrien.crivelli@gmail.com> Co-authored-by: Ryan McAllen <rhyno@rhynodesigns.com> Co-authored-by: Flinsch <220455+Flinsch@users.noreply.github.com> Co-authored-by: Jan Sverre Riksfjord <jasverix@gmail.com> Co-authored-by: Max Kalyabin <maksim@kalyabin.ru> Co-authored-by: Sébastien Despont <sebastien.despont@gmail.com> Co-authored-by: Guilliam Xavier <guilliamxavier@users.noreply.github.com> Co-authored-by: Gianluca Giovinazzo <g.giovinazzo@gmail.com> Co-authored-by: Alexander M. Turek <me@derrabus.de> Co-authored-by: Martins Sipenko <martins.sipenko@gmail.com> * Inherited Scrutinizer Recommendations - 2 of 3 (#1807) * Make DefinedNames Samples Consistent With Other Samples (#1707) All other Samples write to temporary directory. DefinedNames samples write to main directory, which (a) means they aren't stored with others, and (b) they aren't ignored by git so look like changed files. The tests are also simplified by requiring Header rather than Bootstrap, making use of Helper. * Resolve XSS Vulnerability in the HTML Writer (#1719) Resolve XSS Vulnerability in the HTML Writer * Drop Travis * Automatic GitHub releases from git tags * Improve Coverage in src/PhpSpreadsheet There are no changes to code. Additional tests are added, so that the following 6 items now have 100% test coverage: - Comment - DefinedName - DocumentGenerator - IOFactory - NamedFormula - NamedRange * Changes for Scrutinizer Two changes to fix minor problems reported by Scrutinizer. * Spelling: Tou -> You * Fix for 1735 (Incorrect activeSheetIndex after RemoveSheetByIndex) (#1743) This is a fix for issue #1735. It adds tests for this situation, and similar situations involving adding new sheets and accessing existing ones. Coverage for Spreadsheet.php increases from 69% to 75% as a result. * Update change log * Fix for 3 Issues Involving ReadXlsx and NamedRange (#1742) * Fix for 3 Issues Involving ReadXlsx and NamedRange Issues #1686 and #1723, which provide sample spreadsheets, are probably solved by this ticket. Issue #1730 is also probably solved, but I have no way to verify. There are two problems with how PhpSpreadsheet is handling things now. Although the first problem is much less severe, and isn't really a factor in the issues named above, it is helpful to get it out of the way first. If you define a named range in Excel, and then delete the sheet where the range exists, Excel saves the range as #REF!. If there is a cell which references the range, it will similarly have the value #REF! when you open the Excel file. Currently, PhpSpreadsheet discards the #REF! definition, so a cell which references the range will appear as #NAME? rather than #REF!. This PR changes the behavior so that PhpSpreadsheet retains the #REF! definition, and cells which reference it will appear as #REF!. The second problem is the more severe, and is, I believe, responsible for the 3 issues identified above. If you define a named range and the sheet on which the range is defined does not exist at the time, Excel will save the range as something like: '[1]Unknown Sheet'!$A$1 If a cell references such a range, Excel will again display #REF!. PhpSpreadsheet currently throws an Exception when it encounters such a definition while reading the file. This PR changes the behavior so that PhpSpreadsheet saves the definition as #REF!, and cells which reference it will behave similarly. For the record, I will note that Excel does not magically recalculate when a missing sheet is subsequently added, despite the fact that the reference might now become resolvable. PhpSpreadsheet behaves likewise. * Remove Dead Code in Test Identified it after push but before merge. * Update change log * Apply Column and Row Styles to Existing Cells (#1721) * Apply Column and Row Styles to Existing Cells This is a fix for issue #1712. When a style is applied to an entire row or column, it is currently only effective for cells which don't already contain a value. The code needs to iterate through existing cells in the row/column in order to apply the style to them. This could be considered a breaking change, however, I believe that the change makes things operate as users would expect, and that the existing implementation is incomplete. The change also removes protected element conditionalStyles from the Style class. That element is an unused remnant, and can no longer be set or retrieved - methods getConditionalStyles and setConditionalStyles actually act on an element in the Worksheet class. Finally, additional tests are added so that Style, and in fact the entire Style directory, now has 100% test coverage. * Scrutinizer Changes Scrutinizer flagged 6 statements. 5 can be easily corrected. One is absolutely wrong (it thinks iterating through cells in column can return null). Let's see if we can satisfy it. * Remove Exception For CellIterator on Empty Row/Column For my first attempt at this change, which corrects a bug by updating styles for non-empty cells when a style is set on a row or column, I wished to make things more efficient by using setIterateOnlyExistingCells, something which the existing documentation recommends. This caused an exception to be generated when the row or column is empty. So I removed that part of the change while I researched what was going on. I have completed that research. The existing code does throw an exception when the row/column is empty and iterateOnlyExistingCells is true. However, that does not seem like a reasonable action. This situation is analagous to iterating over an empty array, and that action is legal and does not throw. The same should apply here. There were no tests for this situation, and now there are. I have added additional tests, and coverage for all of RowCellIterator, ColumnCellIterator, and CellIterator are all now 100%. Some of my new tests were added in new members, because the existing tests all relied on mocking, which was not the best choice for the new tests. One of the existing tests for RowCellIteratorTest (testSeekOutOfRange) was wrong; it issued the expected exception, but for the wrong reason. I have added an additional test to ensure that it fails "correctly". The existing documentation says that the default value for IterateOnlyExistingCells is true. In fact, the default value is false. I have corrected the documentation. * More Scrutinizer I believe its analysis is incorrect, but this should silence it. * DocBlock Correction ColumnCellIterator DocBlock for current indicated it could return null or Cell, but it can really return only Cell. This had caused Scrutinizer to complain earlier. * PHP8 Environment Appears to be Fixed Cosmetic change to Doc member. I suspect there is a way to rerun all the tests without another push, but I have been unable to figure out how. * Update change log * TextData Coverage and Minor Bug Fixes (#1744) This had been intended to get 100% coverage for TextData functions, and it does that. However, some minor bugs requiring source changes arose during testing. - the Excel CHAR function restricts its argument to 1-255. PhpSpreadsheet CHARACTER had been allowing 0+. Also, there is no need to test if iconv exists, since it is part of Composer requirements. - The DOLLAR function had been returning NUM for invalid arguments. Excel returns VALUE. Also, negative amounts were not being handled correctly. - The FIXEDFORMAT function had been returning NUM for invalid arguments. Excel FIXED returns VALUE. * Replace anti-xss with html purifier (#1751) * Replace voku/anti-xss with ezyang/htmlpurifier. Despite anti-xss being a smaller footprint dependency, an a better license fit with our MIT license, there are issues with it's automatic it sanitisation of global variables causing side effects * Additional unit tests for xss in html writer cell comments * Fix bug #1626 where values of 0 were "rounded" up/down as if they were not 0 (#1627) * Fix bug where values of 0 were "rounded" up/down as if they were not 0 * Update change log * Fix for #1612 - SLK Long File Name (#1706) Issue has been marked stale, but ... Sylk read sets worksheet title to filename (minus .slk). If that is >31 characters, PhpSpreadsheet throws Exception. This change truncates sheet title, as Excel does, to 31 characters. * Update change log * worksheet: fix if cellValue does not exist (#1727) The condition is FALSE if the cell does not exist in the flipped table, but anyway, it is sent in to a method requiring 'string' type, causing it to fail. * fixes #1655 issue (#1656) Resolve problem with incorrectly defined hyperlinks * Add 'ps' suffix to printer settings resources IDs (#1690) * Add 'ps' suffix to printer settings resources IDs * Update change log * Fix pixelsToPoints conversion (for HTML col width) (#1733) * DocBlock Change in Styles/Conditional (#1697) Scrutinizer reported a minor error in a test involving a module which I was not changing. Styles/Conditional function setConditions can take a scalar or an array as a parameter, but DocBlock says it only expects array. I did not wish to add the extra module to my PR, but made a note to self to fix that after PR was installed. That has now happened, and it makes for a good case for me to see all the PHP8/Composer2/etc. changes that have happened recently. * Merge pull request #1698 * Merge pull request #4 from PHPOffice/master * Restore Omitted Read XML Test * Fix for bug #1592 (UPDATED) (#1623) * Fix for Xls when BIFF8 SST (FCh) has bad Shared string length * Update change log * Add nightly PHP 8.1 dev to github actions (#1763) * Fix compatibility with ext-gd on php 8 (#1762) * CSV - Guess Encoding, Handle Null-string Escape (#1717) * CSV - Guess Encoding, Handle Null-string Escape This is in response to issue #1647 (detect CSV character encoding). First, my tests with mb_detect_encoding indicate that it doesn't work well enough; regardless, users can always do that on their own if they deem it useful. Rolling my own is also troublesome, but I can at least: a. Check for BOM (UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE). b. Do some heuristic tests for each of the above encodings. c. Fallback to a user-specified encoding (default CP1252) if a and b don't yield result. I think this is probably useful enough to include, and relatively easy to expand if other potential encodings should be considered. Starting with PHP7.4, fgetcsv allows specification of null string as escape character in fgetcsv. This is a much better choice than the PHP (and PhpSpreadsheet) default of backslash in that it handles the file in the same manner as Excel does. There is one statement in Reader/CSV which would be adversely affected if the caller so specified (building a regular expression under the assumption that escape character is a single character). Fix that statement appropriately and add tests. * Update changelog * Update Units of Measure supported by the CONVERT() function (#1768) Now supports all current UoM in all categories, with both 1- and 2-character multiplier prefixes, and binary multiplier prefixes, including the new Temperature scales * Changelog for 1.16.0 release * Fix date tests withut specified year for current year 2021 (#1774) * Mrand of zero to any multiple should return 0 (#1773) * Inherited Scrutinizer Recommendations - 2 of 3 I tried to sync my fork with the main project, as I have done several times before. However, the GitHub interface to do this had changed, and it appears that I did not make the optimal selection when I had a choice. Consequently, all the merges that happened to base between the last time I synchronized and this time appear to be part of any PR that I push. "Files changed" remains correct for my new PRs, but there appear to be many more commits involved than is actually the case. I will, at some point, delete and re-create my fork, and pay much closer attention in future when I want to sync my fork with the main project. Because of this set-up, Scrutinizer reports flaws in code that I haven't actually changed in my PRs #1799 and #1800. It still passes them, but, as long as I'm aware of the problems, I may as well attempt to correct them. The following are not part of those PRs: - 5 problems spread over 4 different members - 12 problems in Calculation/Engineering - 15 problems in Reader/XML I shall attempt to resolve these via 3 separate PRs, of which this is the second. * Fixed Most of the Problems, But Some New Ones Cropped Up Trying once more to satisfy Scrutinizer. Co-authored-by: Mark Baker <mark@lange.demon.co.uk> Co-authored-by: Adrien Crivelli <adrien.crivelli@gmail.com> Co-authored-by: Ryan McAllen <rhyno@rhynodesigns.com> Co-authored-by: Flinsch <220455+Flinsch@users.noreply.github.com> Co-authored-by: Jan Sverre Riksfjord <jasverix@gmail.com> Co-authored-by: Max Kalyabin <maksim@kalyabin.ru> Co-authored-by: Sébastien Despont <sebastien.despont@gmail.com> Co-authored-by: Guilliam Xavier <guilliamxavier@users.noreply.github.com> Co-authored-by: Gianluca Giovinazzo <g.giovinazzo@gmail.com> Co-authored-by: Alexander M. Turek <me@derrabus.de> Co-authored-by: Martins Sipenko <martins.sipenko@gmail.com> * Inherited Scrutinizer Recommendations - 3 of 3 (#1808) * Make DefinedNames Samples Consistent With Other Samples (#1707) All other Samples write to temporary directory. DefinedNames samples write to main directory, which (a) means they aren't stored with others, and (b) they aren't ignored by git so look like changed files. The tests are also simplified by requiring Header rather than Bootstrap, making use of Helper. * Resolve XSS Vulnerability in the HTML Writer (#1719) Resolve XSS Vulnerability in the HTML Writer * Drop Travis * Automatic GitHub releases from git tags * Improve Coverage in src/PhpSpreadsheet There are no changes to code. Additional tests are added, so that the following 6 items now have 100% test coverage: - Comment - DefinedName - DocumentGenerator - IOFactory - NamedFormula - NamedRange * Changes for Scrutinizer Two changes to fix minor problems reported by Scrutinizer. * Spelling: Tou -> You * Fix for 1735 (Incorrect activeSheetIndex after RemoveSheetByIndex) (#1743) This is a fix for issue #1735. It adds tests for this situation, and similar situations involving adding new sheets and accessing existing ones. Coverage for Spreadsheet.php increases from 69% to 75% as a result. * Update change log * Fix for 3 Issues Involving ReadXlsx and NamedRange (#1742) * Fix for 3 Issues Involving ReadXlsx and NamedRange Issues #1686 and #1723, which provide sample spreadsheets, are probably solved by this ticket. Issue #1730 is also probably solved, but I have no way to verify. There are two problems with how PhpSpreadsheet is handling things now. Although the first problem is much less severe, and isn't really a factor in the issues named above, it is helpful to get it out of the way first. If you define a named range in Excel, and then delete the sheet where the range exists, Excel saves the range as #REF!. If there is a cell which references the range, it will similarly have the value #REF! when you open the Excel file. Currently, PhpSpreadsheet discards the #REF! definition, so a cell which references the range will appear as #NAME? rather than #REF!. This PR changes the behavior so that PhpSpreadsheet retains the #REF! definition, and cells which reference it will appear as #REF!. The second problem is the more severe, and is, I believe, responsible for the 3 issues identified above. If you define a named range and the sheet on which the range is defined does not exist at the time, Excel will save the range as something like: '[1]Unknown Sheet'!$A$1 If a cell references such a range, Excel will again display #REF!. PhpSpreadsheet currently throws an Exception when it encounters such a definition while reading the file. This PR changes the behavior so that PhpSpreadsheet saves the definition as #REF!, and cells which reference it will behave similarly. For the record, I will note that Excel does not magically recalculate when a missing sheet is subsequently added, despite the fact that the reference might now become resolvable. PhpSpreadsheet behaves likewise. * Remove Dead Code in Test Identified it after push but before merge. * Update change log * Apply Column and Row Styles to Existing Cells (#1721) * Apply Column and Row Styles to Existing Cells This is a fix for issue #1712. When a style is applied to an entire row or column, it is currently only effective for cells which don't already contain a value. The code needs to iterate through existing cells in the row/column in order to apply the style to them. This could be considered a breaking change, however, I believe that the change makes things operate as users would expect, and that the existing implementation is incomplete. The change also removes protected element conditionalStyles from the Style class. That element is an unused remnant, and can no longer be set or retrieved - methods getConditionalStyles and setConditionalStyles actually act on an element in the Worksheet class. Finally, additional tests are added so that Style, and in fact the entire Style directory, now has 100% test coverage. * Scrutinizer Changes Scrutinizer flagged 6 statements. 5 can be easily corrected. One is absolutely wrong (it thinks iterating through cells in column can return null). Let's see if we can satisfy it. * Remove Exception For CellIterator on Empty Row/Column For my first attempt at this change, which corrects a bug by updating styles for non-empty cells when a style is set on a row or column, I wished to make things more efficient by using setIterateOnlyExistingCells, something which the existing documentation recommends. This caused an exception to be generated when the row or column is empty. So I removed that part of the change while I researched what was going on. I have completed that research. The existing code does throw an exception when the row/column is empty and iterateOnlyExistingCells is true. However, that does not seem like a reasonable action. This situation is analagous to iterating over an empty array, and that action is legal and does not throw. The same should apply here. There were no tests for this situation, and now there are. I have added additional tests, and coverage for all of RowCellIterator, ColumnCellIterator, and CellIterator are all now 100%. Some of my new tests were added in new members, because the existing tests all relied on mocking, which was not the best choice for the new tests. One of the existing tests for RowCellIteratorTest (testSeekOutOfRange) was wrong; it issued the expected exception, but for the wrong reason. I have added an additional test to ensure that it fails "correctly". The existing documentation says that the default value for IterateOnlyExistingCells is true. In fact, the default value is false. I have corrected the documentation. * More Scrutinizer I believe its analysis is incorrect, but this should silence it. * DocBlock Correction ColumnCellIterator DocBlock for current indicated it could return null or Cell, but it can really return only Cell. This had caused Scrutinizer to complain earlier. * PHP8 Environment Appears to be Fixed Cosmetic change to Doc member. I suspect there is a way to rerun all the tests without another push, but I have been unable to figure out how. * Update change log * TextData Coverage and Minor Bug Fixes (#1744) This had been intended to get 100% coverage for TextData functions, and it does that. However, some minor bugs requiring source changes arose during testing. - the Excel CHAR function restricts its argument to 1-255. PhpSpreadsheet CHARACTER had been allowing 0+. Also, there is no need to test if iconv exists, since it is part of Composer requirements. - The DOLLAR function had been returning NUM for invalid arguments. Excel returns VALUE. Also, negative amounts were not being handled correctly. - The FIXEDFORMAT function had been returning NUM for invalid arguments. Excel FIXED returns VALUE. * Replace anti-xss with html purifier (#1751) * Replace voku/anti-xss with ezyang/htmlpurifier. Despite anti-xss being a smaller footprint dependency, an a better license fit with our MIT license, there are issues with it's automatic it sanitisation of global variables causing side effects * Additional unit tests for xss in html writer cell comments * Fix bug #1626 where values of 0 were "rounded" up/down as if they were not 0 (#1627) * Fix bug where values of 0 were "rounded" up/down as if they were not 0 * Update change log * Fix for #1612 - SLK Long File Name (#1706) Issue has been marked stale, but ... Sylk read sets worksheet title to filename (minus .slk). If that is >31 characters, PhpSpreadsheet throws Exception. This change truncates sheet title, as Excel does, to 31 characters. * Update change log * worksheet: fix if cellValue does not exist (#1727) The condition is FALSE if the cell does not exist in the flipped table, but anyway, it is sent in to a method requiring 'string' type, causing it to fail. * fixes #1655 issue (#1656) Resolve problem with incorrectly defined hyperlinks * Add 'ps' suffix to printer settings resources IDs (#1690) * Add 'ps' suffix to printer settings resources IDs * Update change log * Fix pixelsToPoints conversion (for HTML col width) (#1733) * DocBlock Change in Styles/Conditional (#1697) Scrutinizer reported a minor error in a test involving a module which I was not changing. Styles/Conditional function setConditions can take a scalar or an array as a parameter, but DocBlock says it only expects array. I did not wish to add the extra module to my PR, but made a note to self to fix that after PR was installed. That has now happened, and it makes for a good case for me to see all the PHP8/Composer2/etc. changes that have happened recently. * Merge pull request #1698 * Merge pull request #4 from PHPOffice/master * Restore Omitted Read XML Test * Fix for bug #1592 (UPDATED) (#1623) * Fix for Xls when BIFF8 SST (FCh) has bad Shared string length * Update change log * Add nightly PHP 8.1 dev to github actions (#1763) * Fix compatibility with ext-gd on php 8 (#1762) * CSV - Guess Encoding, Handle Null-string Escape (#1717) * CSV - Guess Encoding, Handle Null-string Escape This is in response to issue #1647 (detect CSV character encoding). First, my tests with mb_detect_encoding indicate that it doesn't work well enough; regardless, users can always do that on their own if they deem it useful. Rolling my own is also troublesome, but I can at least: a. Check for BOM (UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE). b. Do some heuristic tests for each of the above encodings. c. Fallback to a user-specified encoding (default CP1252) if a and b don't yield result. I think this is probably useful enough to include, and relatively easy to expand if other potential encodings should be considered. Starting with PHP7.4, fgetcsv allows specification of null string as escape character in fgetcsv. This is a much better choice than the PHP (and PhpSpreadsheet) default of backslash in that it handles the file in the same manner as Excel does. There is one statement in Reader/CSV which would be adversely affected if the caller so specified (building a regular expression under the assumption that escape character is a single character). Fix that statement appropriately and add tests. * Update changelog * Update Units of Measure supported by the CONVERT() function (#1768) Now supports all current UoM in all categories, with both 1- and 2-character multiplier prefixes, and binary multiplier prefixes, including the new Temperature scales * Changelog for 1.16.0 release * Fix date tests withut specified year for current year 2021 (#1774) * Mrand of zero to any multiple should return 0 (#1773) * Inherited Scrutinizer Recommendations - 3 of 3 I tried to sync my fork with the main project, as I have done several times before. However, the GitHub interface to do this had changed, and it appears that I did not make the optimal selection when I had a choice. Consequently, all the merges that happened to base between the last time I synchronized and this time appear to be part of any PR that I push. "Files changed" remains correct for my new PRs, but there appear to be many more commits involved than is actually the case. I will, at some point, delete and re-create my fork, and pay much closer attention in future when I want to sync my fork with the main project. Because of this set-up, Scrutinizer reports flaws in code that I haven't actually changed in my PRs #1799 and #1800. It still passes them, but, as long as I'm aware of the problems, I may as well attempt to correct them. The following are not part of those PRs: - 5 problems spread over 4 different members - 12 problems in Calculation/Engineering - 15 problems in Reader/XML I shall attempt to resolve these via 3 separate PRs, of which this is the third. * The Usual Fixed some Scrutinizer problems, some new ones popped up. * More Scrutinizer I think it's wrong in a lot of these cases. Although I am working around all of them, I intend to file a bug report with them. Co-authored-by: Mark Baker <mark@lange.demon.co.uk> Co-authored-by: Adrien Crivelli <adrien.crivelli@gmail.com> Co-authored-by: Ryan McAllen <rhyno@rhynodesigns.com> Co-authored-by: Flinsch <220455+Flinsch@users.noreply.github.com> Co-authored-by: Jan Sverre Riksfjord <jasverix@gmail.com> Co-authored-by: Max Kalyabin <maksim@kalyabin.ru> Co-authored-by: Sébastien Despont <sebastien.despont@gmail.com> Co-authored-by: Guilliam Xavier <guilliamxavier@users.noreply.github.com> Co-authored-by: Gianluca Giovinazzo <g.giovinazzo@gmail.com> Co-authored-by: Alexander M. Turek <me@derrabus.de> Co-authored-by: Martins Sipenko <martins.sipenko@gmail.com> * Fix/1674 (#1688) * Treat inline strings like strings in Open Document because it has no specific inline-string format * implement data-type error Co-authored-by: Mark Baker <mark@lange.demon.co.uk> * Fixed reading XSLS style alignments from XML (#1710) The attribute `$alignmentXml` given to the private method `readAlignmentStyle` is the alignment XML tag that contains the alignment data itself. But inside that method all data are read from another `alignment` XML tag within that given tag. This redundant child-node access resulted in the following error- / notice-message: `PHP Notice: Trying to access array offset on value of type null in /foo/bar/baz/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx/Styles.php on line 146` These changes remove the redundant child-node access in …
Общие предварительные проверки.
### Ничего не видно. Страница пустая и белая.
Это происходит, когда отчеты об ошибках отключены и произошла фатальная ошибка (часто синтаксическая ошибка). Если это происходит не на продакшн версии, а при разработке, то достаточно включить отображение ошибок. Как это сделать, написано тут:
Как и какими средствами находить ошибки в PHP коде — Сообщения об ошибках PHP. Если это продакшн версия, то ошибки обычно логируются в специальный файл. Как правило на Линукс системах лежит в папке /var/log/apache2
с названием «error.log» либо «название-сайта-error.log». Там можно найти конкретное сообщение об ошибке.
Просто напоминание: для проверки на корреткность логики кода, когда работает, но не так, как ожидалось, используйте отладку
### Код не запускается / Выводится код как он есть в PHP
Если не видно результата от PHP-кода и/или видно части PHP кода прямо на странице как они есть, значит PHP не выполняется. Если посмотреть в исходный код страницы в своем браузере (View Source),
то поскольку код PHP пишется в тегах <?php ?>
, браузер попытается интерпретировать их как теги HTML и результат может выглядеть несколько запутанным.
Надо знать, чтобы запустить PHP-скрипты, необходимо:
-
веб-сервер, который выполняет скрипт
-
установить расширение файла на
.php
, иначе веб-сервер не будет интерпретировать его как таковой (Если вы его не перенастроите (всё можно перенастроить)) -
обращаться к файлу
.php
через веб-сервер! Если просто дважды кликнуть файл, он, скорее всего, откроется в браузере с таким адресом:file://C:/path/to/my/file.php
Это полностью игнорирует любой запущенный веб-сервер, и файл не интерпретируется. Нужно «посетить» URL-адрес файла именно на веб-сервере. Примерно так:
http://localhost/my/file.php
Напоминание: Если используете короткие открытые теги <?
вместо <?php
, надо проверить, что в конфигурации PHP (php.ini) включена опция short_open_tag = On
→ Ссылка
Автор решения: Алексей Шиманский
### Notice: Undefined variable
Происходит при попытке использовать переменную, которая ранее не была определена. То есть обращаетесь, например, к переменной $test
, пишите if($test){ echo $actionMessage; }
,
а в коде выше её нет, либо она в другой области видимости (например за пределами анонимной функции)
$prefix = "Blueberry";
$food = ["cake", "cheese", "pie"];
$prefixedFood = array_map(function ($food) { // должно быть array_map(function ($food) use ($prefix) {
// $prefix не определён, т.к. в другой области видимости ^^^^^^^^^^^^ надо передать в функцию
return "${prefix} ${food}";
}, $food);
или определяется только в одной из веток if
, а код попадает в другую
$a = 10;
if($a == 5) {
$user_location = 'Paris';
} else {
}
echo $user_location;
и т.д. Смотрите наличие этой переменной выше по коду и в правильной области видимости!
### Notice: Undefined property
Эта ошибка означает то же, что выше, но относится к свойству объекта. Т.е. например обращение if($obj->test){ echo $actionMessage; }
, при отсутствии свойства test
в объекте вызовет ошибку.
### Warning: [function] expects parameter 1 to be resource, boolean given
Самая распространённая проблема mysql_fetch_array() expects parameter 1 to be resource (or mysqli_result), boolean given. См. ссылку для подробного описания.
Сама ошибка говорит о том, что в какую-либо из функций подали на вход переменную с типом boolean
, а она ждала тип «ресурс».
Ресурс — это тип, такой же как строки, целые числа и пр.
Некоторые функции в PHP возвращают данный тип, например mysql_query
, curl_init
, fopen
и многие другие (смотрите в документации, что возвращает функция).
Однако если функция отработала некорректно, то в качестве результата она может вернуть false
(всё тот же fopen
, например, или mysql_query
). Поэтому надо проверять что вернула функция: boolean
(по-сути, неудачу операции) или корректный дескриптор.
$fp = fopen(...);
if (!$fp) {
trigger_error('Failed to allocate resource');
exit;
}
$data = fread($fp, 1024);
### Warning: [function]: failed to open stream
Происходит, когда вызывается файл (обычно с помощью include
, require
или fopen
). Частые варианты проблемы:
- Файл не существует в принципе
- Отсутствует даже сама папка
- Путь до файла неверный
- Путь до файла относительный (а указали абсолютный или неправильно рассчитан путь, не учтена вложенность и пр.)
- Путь подключаемого файла (через include, require) неверный
- Путь вроде похожий, но на самом деле там опечатки
- Неправильные права на папку или файл (например 000 вместо 755)
- Файлы в ПО компилируются и кэшируются. Путь поменялся, а кэш забыли сбросить
Одна из распространенных ошибок — не использовать абсолютный путь. Это можно легко решить, используя полный путь или магические константы, такие как __DIR__
или dirname (__ FILE__)
:
include __DIR__ . '/inc/globals.inc.php';
или
require dirname(__FILE__) . '/inc/globals.inc.php';
### Warning: Division by zero
Происходит деление на ноль. Это может быть не только потому, что в переменной-делителе 0, но и если в ней NULL
. Самое простое это воспользоваться отладкой. и посмотреть почему в переменной не то значение, что ожидалось. Нужно переписать свое выражение так, чтобы проверить, что значение не равно 0. Также можно воспользоваться try/catch для отлова исключения и уведомления об этом пользователя, например.
$var1 = 0;
$var2 = 5;
try {
$var3 = $var2 / $var1;
} catch (DivisionByZeroError $e) {
echo 'Произошло деление на ноль!';
}
### Warning: Illegal string offset ‘XXX’ | Uncaught TypeError: Cannot access offset of type string on string (PHP 8.0)
Происходит при попытке получить доступ к элементу массива с синтаксисом квадратных скобок, но делаете это в строке, а не в массиве, поэтому операция явно не имеет смысла. Пример
$myString = "string";
// Ту всё ок
echo $myString[0]; // s
echo $myString[1]; // t
echo $myString[2]; // r
// ...
// !! Ошибка:
echo $myString['port'];
// !! Warning: Illegal string offset 'port' in ...
Если известно, что в переменной должен (обязан) быть массив — можно воспользоваться отладкой, чтобы отследить, почему в какой момент в переменной вместо массива значение меняется на строковое. Если не известно, прилетит ли массив или строка, но нужен массив, то можно воспользоваться проверками типа is_array (определяет, является ли переменная массивом), in_array (проверяет, присутствует ли в массиве значение), isset (определяет, была ли установлена переменная значением, отличным от null)
$string = "string";
$array = array('port' => 'the_port');
if (is_array($string) && isset($string['port'])) {
// Всё отлично, мы никогда не попадём сюда
echo $string['port'];
}
if (is_array($array) && isset($array['port'])) {
// Ok!
echo $array['port']; // the_port
}
if (is_array($array) && isset($array['unset_key'])) {
// Всё отлично, мы никогда не попадём сюда
echo $array['unset_key'];
}
// Аналогично вышенаписанному, но с применением array_key_exists
if (is_array($array) && array_key_exists('port', $array)) {
// Ok!
echo $array['port']; // the_port
}
### Warning: count(): Parameter must be an array or an object that implements Countable
Параметр, передаваемый в функцию count()
, должен быть исчисляемым/то что можно посчитать. Обычно это массив.
Вероятная проблема заключается в том, что было передано скалярное значение, такое как строка или целое число, или объект, который не реализует интерфейс Countable
. Использование var_dump()
для рассматриваемой переменной может показать, так ли это.
→ Ссылка
Автор решения: Алексей Шиманский
### Fatal error: Call to a member function … on a non-object
Происходит обычно в случае xyz->method()
, где xyz
по какой-то причине не является объектом, как ожидалось, и, следовательно, этот method
не может быть вызван.
Нужно убедиться, что объект на самом деле является объектом, прежде чем вызывать его методы. Т.е. в примере выше нужно быть уверенным,
что xyz
— это объект, а не, например, null
(наиболее часто встречается именно это) или false
.
Как пример:
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
В приведенном примере запрос не может быть подготовлен, и prepare()
вернёт false
. Как следствие будет происходить попутка вызвать метод execute()
у булевого типа, а не у объекта.
Выясните, почему функция вернула логическое значение вместо объекта. Например, проверьте объект $pdo
на предмет последней произошедшей ошибки. Подробности того, как отлаживать это, будут зависеть от того, как обрабатываются ошибки для конкретной рассматриваемой функции/объекта/класса. Чаще всего ошибка возникает потому, что в коде отсутствуют проверки на наличие ошибок.
Другая проблема может заключаться в условном создании объекта и последующей попытке вызвать метод вне этого условного блока. Например
if ($someCondition) {
$myObj = new MyObj();
}
// ...
$myObj->someMethod();
Смотрите наличие этой переменной выше по коду и в правильной области видимости!
### Fatal error: Call to undefined function XXX
Происходит, когда происходит вызов функции, которая еще не определена. Распространенные причины: отсутствие расширений, неподключенный файл с функциями (через include
/require
), условное объявление функции (см. пример ниже), объявлении функции в функциях или просто из-за опечаток.
Условное объявление функции:
$someCondition = false;
if ($someCondition === true) {
function fn() {
return 1;
}
}
echo fn(); // Ошибка, т.к. условие никогда не выполнится
Объявление функции в функции
function createFn() {
function fn() {
return 1;
}
}
echo fn(); // Ошибка, т.к. другая область видимости
Примечание: последующие вызовы createFn()
вызовут ошибку о повторном объявлении существующей функции.
Также можно увидеть эту ошибку для встроенной функции PHP. Можно попробовать найти функцию в официальном руководстве и проверить, к какому «расширению» (модулю PHP) оно принадлежит и какие версии PHP его поддерживают. В случае отсутствия расширения — нужно установить его и включить его в php.ini
.
В случае, если функция находится в другом файле — не забудьте его подключить перед использованием функции
В случае опечатки — исправьте опечатку %)
### Fatal error: Cannot redeclare class [class name]
а также
### Fatal error: Cannot redeclare [function name]
Это означает, что вы либо дважды используете одно и то же имя функции/класса и нужно переименовать одну/один из них, либо это потому, что использовали require
или include
, где должны использовать require_once
или include_once
.
Когда класс или функция объявляются в PHP, они неизменяемы и не могут быть позже объявлены с новым значением.
Пример:
class.php
<?php
class MyClass {
public function doSomething() { // что-то тут }
}
index.php
<?php
function doStuff() {
require 'class.php';
$obj = new MyClass;
$obj->doSomething();
}
doStuff();
doStuff();
Второй вызов doStuff()
вызовет указанную выше ошибку. Изменив require
на require_once
, мы можем быть уверены, что файл, содержащий определение MyClass
, будет загружен только один раз, и ошибки можно будет избежать.
Не лишним будет использовать автозагрузку, и такие стандарты, как PSR-4 (стандарт по автозагрузке). или даже устаревший PSR-0, в значительной степени избавляют от необходимости использовать require
/include
самостоятельно (за исключением нескольких странных крайних случаев).
См. также Автозагрузка классов с помощью Composer., Автозагрузка классов с помощью Composer2, Автозагрузка классов с помощью Composer3
### Fatal error: Can’t use function return value in write context
Обычно это происходит при использовании функции напрямую с empty
if (empty(is_null(null))) {
echo 'empty';
}
Это связано с тем, что empty — это языковая конструкция, а не функция. Её нельзя вызвать с выражением в качестве аргумента в версиях PHP до 5.5. До PHP 5.5 аргумент для empty()
должен быть variable (то есть переменной), но в PHP 5.5+ допускается произвольное выражение (например, возвращаемое значение функции).
Не смотря на своё название, empty
на самом деле не проверяет, является ли переменная «пустой». Она проверяет существует ли переменная или её значение равно false
.
Выражения (такие как is_null (null)
в примере) всегда будут считаться существующими, поэтому здесь empty
только проверяет, равно ли оно false
. Можно заменить здесь empty()
на !
, например
if (! is_null (null))
или явно сравнить с false
, например
if (is_null (null) == false)
→ Ссылка
Автор решения: Алексей Шиманский
### Fatal error: Declaration of AAA::BBB() must be compatible with that of CCC::BBB()
Происходит при наследовании (или использовании трейтов), когда в методе в классе наследнике сигнатура метода отличается от класса родителя.
Пример в базовом классе есть метод:
function test($arg1, $arg2 = null)
а в наследнике
function test($arg1, $arg2, $arg3 = null)
То есть уже три аргумента, вместо двух. Или типы аргументов поменялись (хотя бы у одного). Например у arg2
в первом случае был тип int
, а во втором — string
;
### Fatal error: Using $this when not in object context
$this
— это специальная переменная в PHP, которой нельзя ничего присваивать.
Если к ней обращаются в контексте, где её не существует, выдается эта фатальная ошибка.
Возможные моменты возникновения:
-
Если не статический метод вызывается из статического контекста. Пример:
class Foo { protected $var; public function __construct($var) { $this->var = $var; } public static function bar () { // ^^^^^^ echo $this->var; // ^^^^^ } } Foo::bar();
Как исправить: еще раз просмотрите свой код, $this
может использоваться только в контексте объекта и никогда не должен использоваться в статическом методе. Кроме того, статический метод не должен обращаться к не статическому свойству. Используйте self::$static_property
для доступа к статическому свойству.
- Если код из метода класса был скопирован в обычную функцию или куда-либо ещё вне метода и при этом забыли убрать слово
$this
.
Как исправить: Просмотрите код и замените $this
другой переменной подстановки.
### Fatal error: Object of class Closure could not be converted to a string
Это означает, что вы не исполняете/не вызываете свою анонимную функцию (или замыкание), а пытаетесь отправить в поток вывода через echo
/print
/var_dump
/и т.д. саму функцию, а не результат выполнения.
Примеры:
Стрелочная функция
$fn = fn($x = 42) => $x;
echo $fn; // <--- Должно было быть echo $fn() т.е. необходимы круглые скобки
или анонимная функция:
echo function($x = 42) { return $x; }; // должно быть echo (function($x = 42) { return $x; })(2);
Чтобы устранить эту ошибку, необходимо выполнить функцию (как в примере выше echo $fn()
вместо echo $fn
или echo (function($x = 42) { return $x; })(30);
вместо echo function($x = 42) { return $x; };
.
Последний синтаксис называется IIFE (Immediately Invoked Function Expression — функция, которая выполняется сразу же после того, как она была определена.). Она была добавлена в PHP7
### Fatal error: Undefined class constant
Эта ошибка означает, что вы пытались использовать несуществующую константу класса. В отличие от других «неопределенных» уведомлений и предупреждений — это фатальная ошибка и скрипт немедленно останавливается.
В первую очередь следует проверить типографские ошибки. Опечатки, регистр. Нужно убедиться, что константа определена в классе и вызывается с использованием соответствующего пространства имен. Убедиться также, что все соответствующие файлы были подключены.
### Fatal error: Uncaught TypeError: some_function(): Argument #1 must be of type XXX, YYY given
В данном случае ошибка говорит о том, что код попытался вызвать some_function()
и передал неправильный тип данных в качестве одного из аргументов. Например:
declare(strict_types=1);
function multiply(int $x, int $y) {
return $x * $y;
}
echo multiply("3", 4);
Поскольку первый аргумент вызываемой функции имеет скалярный тип int
, а вызов находится в файле, в котором включены строгие типы (stict_types = 1
), при передаче ему тип «строка» возникает ошибка:
Fatal error: Uncaught TypeError: multiply(): Argument #1 ($x) must be of type integer, string given in…
Понятно, что нужно чинить, чтобы в функцию приходил верный тип.
→ Ссылка
Автор решения: Алексей Шиманский
### Notice: Array to string conversion
Происходит при попытки вывести массив как строку. Обычно это происходит, когда применяется функция echo
к массиву или конкатенируется массив в строке.
$arr = array('foo', 'bar');
echo $arr; // Notice: Array to string conversion
$str = 'Something, ' . $arr; // Notice: Array to string conversion
Массив не может быть просто выведен через echo
или объединен со строкой, потому что результат не определен должным образом.
Вероятно, вы хотели сделать что-то вроде этого:
echo $arr[0]; // Выведет: foo
$str = 'Something ' . join(', ', $arr); // Выведет: Something, foo, bar
Или сделать цикл по массиву:
foreach($arr as $key => $value) {
echo "array $key = $value";
}
// Выведет:
// array 0 = foo
// array 1 = bar
Если это уведомление появляется там, где не ожидаете, это означает, что переменная, которую вы считали строкой, на самом деле является массивом. Это означает, что в вашем коде есть ошибка, которая превращает эту переменную в массив вместо ожидаемой строки.
### Notice: Trying to get property of non-object error
Происходит при попытке обращения к свойству объекта, когда объекта нет.
Типичный пример:
$users = json_decode('[{"name": "hakre"}]');
echo $users->name; # Notice: Trying to get property of non-object
В примере выше $users
является массивом (а не объектом) и не имеет никаких свойств. А вот элементы массива — объекты. И обращение $users[0]->name
возымело бы эффект.
Это похоже на доступ к несуществующему индексу или ключу массива (см. Notice: Undefined Index).
Этот пример сильно упрощен. Чаще всего такое уведомление сигнализирует о непроверенном возвращаемом значении, например когда библиотека возвращает NULL
, если объект не существует или просто неожиданное значение, которое не является объектом (например, в результате Xpath
, структуры JSON с неожиданным форматом, XML с неожиданным форматом и т. д.), но код (точнее разработчик) не проверяет наличие такого состояния (что json,xml и пр. могут быть некорректными).
Поскольку эти не-объекты часто обрабатываются дальше, часто происходит фатальная ошибка при вызове метода этого объекта и возникает Fatal error: Call to a member function … on a non-object, которая останавливает работу скрипта в том числе.
Этого можно легко предотвратить, проверив условия ошибки и/или соответствие переменной ожидаемому. Пример DOMXPath:
$result = $xpath->query("//*[@id='detail-sections']/div[1]");
$divText = $result->item(0)->nodeValue; # Notice: Trying to get property of non-object
Тут происходит попытка обратиться к свойству (полю) nodeValue
первого элемента, хотя проверки на то, существует ли он в коллекции $result
не было.
Вместо этого стоит сделать код более явным, назначив переменные объектам, с которыми работает код:
$result = $xpath->query("//*[@id='detail-sections']/div[1]");
$div = $result->item(0);
$divText = "-/-";
if (is_object($div)) {
$divText = $div->nodeValue;
}
echo $divText;
→ Ссылка
Автор решения: Алексей Шиманский
### Notice: Undefined Index ( Undefined array key >= PHP8.0 )
а также
### Undefined offset
Происходит при попытке обратиться по ключу массива, которого нет в массиве.
Типичный пример:
$data = array('foo' => '42', 'bar');
echo $data['spinach']; // Undefined index: spinach
echo $data[1]; // Undefined offset: 1
И spinach
и 1
не существуют и вызовут уведомление. Но немного разные. Undefined offset
означает, что есть пустой ключ массива, происходит обращение по числовому индексу в массиве, которого нет.
Самый типичный пример:
$arr = array('Felix','Jon','Java');
// Будет "Undefined offset" т.к. нумерация начинается с 0,
// и будут индексы 0,1,2, а обращение идёт к индексу 3
echo $arr[3];
Нужно убедиться, что индекс или ключ существует как таковой или до доступа по нему.
Нужно исправить ошибку в программе, чтобы эти индексы действительно существовали, когда это ожидается.
Или нужно проверить, что существуют нужные индексы используя array_key_exists или empty.
Как пример
$data = array('foo' => '42', 'bar');
if (array_key_exists('spinach', $data)) {
echo $data['spinach'];
} else {
echo 'Нет ключа "spinach" в массиве';
}
Как пример ещё: preg_match
если совпадений не найдено — $match
вернёт пустой массив. Но если не проверить и думать, что там всегда будет значение, то можно увидеть эту ошибку
preg_match($regex,$content,$matches)
echo $matches[0]; Undefined offset: 0 так как совпадений не нашлось
### Notice: Uninitialized string offset: XXX
Ошибка возникает когда, скорее всего, идёт попытка перебрать в цикле строку по символам или найти значение в массиве с несуществующим ключом.
Пример, цикл по строке
$string = 'ABCD';
for ($i=0, $len = strlen($string); $i <= $len; $i++){
echo "$string[$i] n";
}
// На выходе будет
A
B
C
D
Notice: Uninitialized string offset: 4 in XXX on line X
Будет показана ошибка потому, что длина строки — 4 символа, а цикл написан от 0 до 4 включительно, то есть 5 итераций.
### Notice: Use of undefined constant XXX — assumed ‘XXX’
или в >=PHP7.2:
### Warning: Use of undefined constant XXX — assumed ‘XXX’ (this will throw an Error in a future version of PHP)
Это уведомление появляется, когда в коде используется токен, который кажется константой, но константа с таким именем не определена.
Одна из наиболее частых причин появления этого уведомления — отсутствие кавычек в строке, используемой в качестве ключа ассоциативного массива:
// Неверно
echo $array[key];
// Верно
echo $array['key'];
Другой распространенной причиной является отсутствие перед именем переменной знака $
(доллар):
// Неверно
echo varName;
// Верно
echo $varName;
Или, возможно, неправильно написали какую-то другую константу или ключевое слово:
// Неверно
$foo = fasle;
// Верно
$foo = false;
Это также может быть признаком того, что необходимое расширение или библиотека PHP отсутствует, когда происходит попытка получить доступ к константе, определенной этой библиотекой.
→ Ссылка
Автор решения: Алексей Шиманский
### Strict Standards: Non-static method [<class>::<method>] should not be called statically
Происходит при попытке вызвать не статический метод в классе в таком форме, как если бы он был статическим. (А также при включенном флаге E_STRICT
в настройках error_reporting()
)
Поясняющий пример:
class HTML {
public function br() { // метод br НЕ статический!
echo '<br>';
}
}
HTML::br(); // <--- два двоеточия должны быть только для вызова статики!
// или
$html = new HTML();
$html::br(); // <--- два двоеточия должны быть только для вызова статики!
Конечно, можно избежать этой ошибки, не добавляя E_STRICT
в `error_reporting(), например
error_reporting (E_ALL & ~ E_STRICT);
Но лучше программировать правильно, чем не правильно!))
Решение состоит в том, чтобы определить вашу предполагаемую статическую функцию как фактическую статическую или или вызвать из контекста:
// решение 1
public static function br() {
echo '<br>';
}
// решение 2
$html = new HTML();
$html->br();
Конечно нужно смотреть на свой контекст и, возможно, переписать класс под правильную логику и вызовы методов.
### Warning: function() expects parameter XXX to be boolean (or integer, string, etc) , YYY given
Если в функцию передается параметр неправильного типа, а PHP не может преобразовать его автоматически, выдается это предупреждение.
Это предупреждение указывает, какой параметр является проблемой и какой тип данных ожидается.
expects
— ожидаетсяgiven
— то, что подаётся на входparameter X
— это какой по счёту параметр
Решение: измените указанный параметр на правильный тип данных. Пример:
echo substr(["foo"], 23);
Отобразится ошибка::
PHP Warning: substr() expects parameter 1 to be string, array given
Ожидается что в первый параметр дадут тип «строка», но в реале дан на вход — тип «массив».
### Deprecated: Array and string offset access syntax with curly braces is deprecated
До версии PHP 7.4.0 доступ к смещениям (offset) строк и элементам массива можно было получить с помощью фигурных скобок {}
:
$string = 'abc';
echo $string{0}; // a
$array = [1, 2, 3];
echo $array{0}; // 1
С PHP 7.4.0 это устарело и отображает ошибку выше
Необходимо использовать квадратные скобки []
для доступа к строковым смещениям и элементам массива:
$string = 'abc';
echo $string[0]; // a
$array = [1, 2, 3];
echo $array[0]; // 1
→ Ссылка